在Perl中处理二维数组令我头疼。无论如何,以下是我的问题:
我有一个循环将一个数组(比如@twoOneArray)推入另一个数组,比如@twoDimArray,然后在循环的下一次迭代开始之前重置,然后再次用新的值集推入@twoDimArray。当我使用以下任一方式打印@twoDimArray时:
print Dumper \@twoDimArray;
它提供输出
输出的
$VAR1 = [
[
'BB',
'AA',
'AA'
],
$VAR1->[0],
$VAR1->[0],
$VAR1->[0]
];
或使用循环
for (my $i=0; $i<4; $i++){
for (my $j=0; $j<4; $j++){
print "$twoDimArray[$i][$j] \n";
}
}
数据重复。
输出的
行= 0 BB AA AA
行= 1 BB AA AA
行= 2 BB AA AA
行= 3 BB AA AA
依旧......
我无法弄清楚为什么两种输出方式都出错了。如果我每次都打印@twoDimArray(在移动到循环的下一次迭代之前,即在使用push函数之后)插入@twoOneArray,那么值似乎很好并且不重复自己,但是在单个go中打印它似乎给出了上述错误。类似的问题已被问到here,但我不确定它是否对我有意义。有什么建议吗?
构建2D数组的代码:
for ($k = 1; $k <= $counter; $k++){
@twoOneArray = (); #reset it when loop starts again
for ($j = 0; $j <= $colsInArray; $j++){
#do stuff to create @twoOneDim
}
push @twoDimArray, \@twoOneArray;
#if I print @twoDimArray if prints fine, with the exact values intact
}
print Dumper \@twoDimArray; #if I print it here it messes up
print "\n";
答案 0 :(得分:10)
Data :: Dumper的输出告诉我你的问题不是打印数组。 Data :: Dumper永远不会说谎(或很少)。
请向我们展示您用于构建阵列的代码。我确定错误出现在那个代码中。
更新:
现在你添加了构建数组的代码,我发现你陷入了一个邪恶的陷阱:你正在将@twoOneArray的引用添加到你的“外部”数组中。但是每次通过循环时引用总是相同的。像这样更改你的代码:
for ($k = 1; $k <= $counter; $k++){
my @twoOneArray; # REALLY reset it when loop starts again
for ($j = 0; $j <= $colsInArray; $j++){
#do stuff to create @twoOneDim
}
push @twoDimArray, \@twoOneArray;
}
..它应该有用。
答案 1 :(得分:4)
你做过这样的事情:
@a = (1, 2, 3);
push @b, \@a;
@a = (2, 3, 4);
push @b, \@a;
# ...
问题在于您将@b
引用推送到@a
。所有引用都指向相同的@a
。 Data::Dumper
通过$VAR->[0]
事件告诉您。
您需要执行以下操作:
$a = [ 1, 2, 3 ];
push @b, $a;
$a = [ 2, 3, 4] ;
push @b, $a;
# ....
这样,[ ... ]
arrayref语法每次都会生成一个新引用的数组。
我建议仔细阅读perlreftut和perlref。
编辑:我看到你发布了你的代码,是的,你正在做我的破坏代码示例。更改为使用[ ... ]
语法,你会没事的。
答案 2 :(得分:4)
其他人已充分回答了您的问题。我想补充说Data::Dumper
的输出对于发现这些问题非常有用:数组的[1]
元素被转储为$VAR1->[0]
- 换句话说,它是对同一个元素的引用存储在[0]
元素中的基础数据值。
答案 3 :(得分:-3)
如果你想要一个数组数组,你应该推送数组引用,例如
my @a = qw(1 2 3 4 5 6 7 8);
my @b = qw(a b c d e f g h);
my @aOfa;
push(@aOfa, \@a);
push(@aOfa, \@b);