检测混合数组中的元素类型
Detecting element types in a mixed array
我正在使用一些代码,这些代码有一个子例程,其中包含一个数组引用作为参数之一。此传入数组中的元素可以是小型数组或字符串。
我想确定每个元素的类型以便执行特定操作(即,如果元素是数组,则通过索引进一步深入研究,如果元素是字符串,则使用字符串)
我试过使用 ref
函数来查询每个数组元素。它似乎适用于数组元素,但如果元素是字符串,我期待 ref
到 return 标量。然而 ref()
似乎 return 什么都没有。我究竟做错了什么?我认为 ref()
会 return 一些东西。
下面是一些示例代码:
my @array = ("string1",
["ele1_arraystr1", "ele1_arraystr2"],
"string2",
["ele4_arraystr1", "ele4_arraystr2"],
"etc");
my $tmp;
&foobar( 30, 20, \@array);
sub foobar {
my($var1, $var2, $array_ref) = @_;
foreach $element (@$array_ref) {
my $tmp = ref($element);
print "Array element type: $tmp\n";
if ($tmp eq 'ARRAY') {
print " ARRAY: $element->[1]\n";
} elsif ($tmp eq 'SCALAR') {
print " SCALAR: $element\n";
} else {
print " Unexpected type: $tmp\n";
}
}
}
输出看起来像这样:
ARRAY element test:
Array element type:
Unexpected type:
Array element type: ARRAY
ARRAY: ele1_arraystr2
Array element type:
Unexpected type:
Array element type: ARRAY
ARRAY: ele4_arraystr2
Array element type:
Unexpected type:
如果参数不是引用,ref
returns 为空字符串。文档说
Returns a non-empty string if EXPR is a reference, the empty string otherwise. The value returned depends on the type of thing the reference is a reference to.
后面的列表(包括 SCALAR
)是 reference 可以指向的类型。
所以当它有一个字符串时,它 returns 一个空字符串,其计算结果为 false。如果你确实知道它是 ARRAY
或字符串,你可以做
if (ref($element) eq 'ARRAY') {
# process the arrayref
}
else {
# process the string
}
最好像您一样专门检查字符串 (false),以便能够检测任何其他类型
my $ref_type = ref($element);
if ($ref_type eq 'ARRAY') {
# process arrayref
}
elsif (not $ref_type) {
# process string
}
else { print "Got type $ref_type\n" }
所有这些都记录在 perldoc perlfunc
under ref
中
ref
return 如果其参数不是引用,则为 false 值。仅当参数是 对 标量
的引用时,它才会 return SCALAR
您可能还需要知道,对于 blessed 数据的引用——一个 Perl 对象——ref
returns class 数据已被祝福,而不是基础数据类型。如果需要区分两者,那么核心Scalar::Util
模块提供了blessed
,其中return是数据加持后的class,而reftype
,其中 return 是基础数据的类型,与 ref
相同
您可以使 foobar
递归处理无限嵌套的数据结构,就像这样
use strict;
use warnings 'all';
use feature 'say';
my @array = (
"string1", [ "ele1_arraystr1", "ele1_arraystr2" ],
"string2", [ "ele4_arraystr1", "ele4_arraystr2" ],
"etc", [ "etc1", "etc2" ]
);
foobar(\@array);
sub foobar {
my ($val, $indent) = (@_);
$indent //= 0;
my $ref = ref $val;
if ( $ref eq 'ARRAY' ) {
foobar($_, $indent+1) for @$val;
}
elsif ( not $ref ) {
say ' ' x $indent, $val;
}
}
输出
string1
ele1_arraystr1
ele1_arraystr2
string2
ele4_arraystr1
ele4_arraystr2
etc
etc1
etc2
或者,如果您的数组总是由交替的字符串和数组引用组成,您可能会发现将其分配给散列会更容易。这将使用字符串作为散列键,并将其相应的数组引用作为散列值
这段代码展示了这个想法。我已经使用 Data::Dump
揭示了结果数据结构
my %data = @array;
use Data::Dump;
dd \%data;
输出
{
etc => ["etc1", "etc2"],
string1 => ["ele1_arraystr1", "ele1_arraystr2"],
string2 => ["ele4_arraystr1", "ele4_arraystr2"],
}
我正在使用一些代码,这些代码有一个子例程,其中包含一个数组引用作为参数之一。此传入数组中的元素可以是小型数组或字符串。
我想确定每个元素的类型以便执行特定操作(即,如果元素是数组,则通过索引进一步深入研究,如果元素是字符串,则使用字符串)
我试过使用 ref
函数来查询每个数组元素。它似乎适用于数组元素,但如果元素是字符串,我期待 ref
到 return 标量。然而 ref()
似乎 return 什么都没有。我究竟做错了什么?我认为 ref()
会 return 一些东西。
下面是一些示例代码:
my @array = ("string1",
["ele1_arraystr1", "ele1_arraystr2"],
"string2",
["ele4_arraystr1", "ele4_arraystr2"],
"etc");
my $tmp;
&foobar( 30, 20, \@array);
sub foobar {
my($var1, $var2, $array_ref) = @_;
foreach $element (@$array_ref) {
my $tmp = ref($element);
print "Array element type: $tmp\n";
if ($tmp eq 'ARRAY') {
print " ARRAY: $element->[1]\n";
} elsif ($tmp eq 'SCALAR') {
print " SCALAR: $element\n";
} else {
print " Unexpected type: $tmp\n";
}
}
}
输出看起来像这样:
ARRAY element test:
Array element type:
Unexpected type:
Array element type: ARRAY
ARRAY: ele1_arraystr2
Array element type:
Unexpected type:
Array element type: ARRAY
ARRAY: ele4_arraystr2
Array element type:
Unexpected type:
如果参数不是引用,ref
returns 为空字符串。文档说
Returns a non-empty string if EXPR is a reference, the empty string otherwise. The value returned depends on the type of thing the reference is a reference to.
后面的列表(包括 SCALAR
)是 reference 可以指向的类型。
所以当它有一个字符串时,它 returns 一个空字符串,其计算结果为 false。如果你确实知道它是 ARRAY
或字符串,你可以做
if (ref($element) eq 'ARRAY') {
# process the arrayref
}
else {
# process the string
}
最好像您一样专门检查字符串 (false),以便能够检测任何其他类型
my $ref_type = ref($element);
if ($ref_type eq 'ARRAY') {
# process arrayref
}
elsif (not $ref_type) {
# process string
}
else { print "Got type $ref_type\n" }
所有这些都记录在 perldoc perlfunc
under ref
ref
return 如果其参数不是引用,则为 false 值。仅当参数是 对 标量
SCALAR
您可能还需要知道,对于 blessed 数据的引用——一个 Perl 对象——ref
returns class 数据已被祝福,而不是基础数据类型。如果需要区分两者,那么核心Scalar::Util
模块提供了blessed
,其中return是数据加持后的class,而reftype
,其中 return 是基础数据的类型,与 ref
您可以使 foobar
递归处理无限嵌套的数据结构,就像这样
use strict;
use warnings 'all';
use feature 'say';
my @array = (
"string1", [ "ele1_arraystr1", "ele1_arraystr2" ],
"string2", [ "ele4_arraystr1", "ele4_arraystr2" ],
"etc", [ "etc1", "etc2" ]
);
foobar(\@array);
sub foobar {
my ($val, $indent) = (@_);
$indent //= 0;
my $ref = ref $val;
if ( $ref eq 'ARRAY' ) {
foobar($_, $indent+1) for @$val;
}
elsif ( not $ref ) {
say ' ' x $indent, $val;
}
}
输出
string1
ele1_arraystr1
ele1_arraystr2
string2
ele4_arraystr1
ele4_arraystr2
etc
etc1
etc2
或者,如果您的数组总是由交替的字符串和数组引用组成,您可能会发现将其分配给散列会更容易。这将使用字符串作为散列键,并将其相应的数组引用作为散列值
这段代码展示了这个想法。我已经使用 Data::Dump
揭示了结果数据结构
my %data = @array;
use Data::Dump;
dd \%data;
输出
{
etc => ["etc1", "etc2"],
string1 => ["ele1_arraystr1", "ele1_arraystr2"],
string2 => ["ele4_arraystr1", "ele4_arraystr2"],
}