为什么Perl打印中的二维数组不正确?

时间:2009-07-16 17:48:56

标签: perl arrays data-structures

在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";

4 个答案:

答案 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。所有引用都指向相同的@aData::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);