如何循环遍历数组数组,如下所示,其中的元素不是引用?我收到错误:"不能使用字符串(" 10")作为ARRAY参考,而#34;严格参考"在使用"但是,如果我拿出元素' 10'和' 11'它打印得很好。
my @array = (
[1, 2, 3, 4, 5],
['x', 'y', 'z'],
10,
11
);
foreach my $x (@array) {
for my $i (0..@$x) {
if (! @$x[$i] eq '') {
print "@$x[$i]\n";
}
}
}
答案 0 :(得分:4)
for my $x (@array) {
# plain scalar, print it and skip to next element
if (!ref($x)) { print "$x\n"; next; }
for my $i (@$x) {
print "$i\n";
}
}
答案 1 :(得分:2)
这一行:
for my $i (0..@$x) {
是您目前的问题所在。对于@array
中的每个值,它会尝试通过@
sigil将其放在Array上下文中。如果您的元素不是对数组的引用,则会抛出您看到的错误。
你可以做的是检查你的内循环开始之前是否正在查看arrayref或标量:
ITER:
foreach my $x (@array) {
if (not ref($x)) {
print "$x\n";
next ITER;
}
for my $i (0..@$x) {
if (! @$x[$i] eq '') {
print "@$x[$i]\n";
}
}
}
答案 2 :(得分:1)
您可以使用他ref
函数来决定如何打印数组元素。如果参数是数组引用,则返回ARRAY
;如果是简单字符串或数值,则返回空字符串。
该程序演示
my @array = (
[1, 2, 3, 4, 5],
['x', 'y', 'z'],
10,
11
);
for my $item (@array) {
if (ref $item) {
print "@$item\n";
}
else {
print "$item\n";
}
}
<强>输出强>
1 2 3 4 5
x y z
10
11
使用条件运算符可以使循环体更简洁。此代码等效
print ref($_) ? "@$_\n" : "$_\n" for @array;
答案 3 :(得分:0)
另一种方法是将任何标量转换为数组引用。这避免了代码重复(以及由此带来的错误风险)。
以你的数组为例:
my @array = (
[1, 2, 3, 4, 5],
['x', 'y', 'z'],
10,
11
);
可以使用临时变量来保存原始值 ($row
),如果它已经是一个数组引用,或者创建一个数组引用来保存原始值(如果它是一个标量)。从那时起,您可以使用熟值代替原始值。例如:
foreach my $row (@array) {
my $cooked = ref $row eq 'ARRAY' ? $row : [ $row ];
print "@$cooked\n";
}
输出:
1 2 3 4 5
x y z
10
11
还可以消除临时变量:
foreach my $row (@array) {
foreach my $item ( @{ ref $row eq 'ARRAY' ? $row : [ $row ] } ) {
print "$item\n"
}
print "\n";
}
这直接将强制代码作为数组(带有 @{
... }
)进行评估并对其进行迭代。输出为:
1
2
3
4
5
x
y
z
10
11
可以使用类似的代码,例如,用于哈希引用 (ref $variable eq 'HASH'
)