【问题标题】:Why isn't the two dimensional array in Perl printing correctly?为什么 Perl 中的二维数组打印不正确?
【发布时间】:2009-07-16 17:48:56
【问题描述】:

在 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,那么这些值似乎很好并且不会重复自己,但是一次打印它似乎给出了上述内容错误。有人问过类似的问题here,但我不确定这对我是否有意义。有什么建议吗?

构建二维数组的代码:

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

【问题讨论】:

  • 在所有 Perl 程序的开头总是 use warnings;use strict;
  • @brad:我愿意。上面的代码只是实际代码的一小部分。所以这就是为什么不在这里写。
  • perldoc perldsc的这个部分,他描述“重复引用同一内存位置”的部分:perldoc.perl.org/perldsc.html#COMMON-MISTAKES整个教程非常好,perldoc perllol也是如此跨度>

标签: perl arrays data-structures


【解决方案1】:

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;
}

.. 它应该可以工作。

【讨论】:

  • @Manni:我从来没有想过这个错误。非常感谢您强调它。我现在一直在调试这个。你帮了我很多,让我很开心!再次感谢:)
【解决方案2】:

你做了这样的事情:

@a = (1, 2, 3);
push @b, \@a;

@a = (2, 3, 4);
push @b, \@a;

# ...

问题在于您将@b 推向@a引用。所有的引用都指向同一个@aData::Dumper 用它的$VAR-&gt;[0] 告诉你。

您需要执行以下操作:

$a = [ 1, 2, 3 ];
push @b, $a;

$a = [ 2, 3, 4] ;
push @b, $a;

# ....

这样,[ ... ] arrayref 语法每次都会创建一个新的引用数组。

我建议仔细阅读 perlreftut 和 perlref。

编辑:我看到你已经发布了你的代码,是的,你正在做我的示例损坏代码。改为使用[ ... ] 语法就可以了。

【讨论】:

    【解决方案3】:

    您的问题已被其他人充分回答。我要补充一点,Data::Dumper 的输出对于发现此类问题很有用:数组的 [1] 元素被转储为 $VAR1-&gt;[0] - 换句话说,它是对存储在[0] 元素。

    【讨论】:

      【解决方案4】:

      如果你想要一个数组数组,你应该推送数组引用,例如

      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);
      

      【讨论】:

      • OP 正在推送数组引用,请查看 Data::Dumper 输出。
      猜你喜欢
      • 1970-01-01
      • 2011-03-02
      • 2020-08-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多