Arrays 在Perl中引用和打印2D数组

Arrays 在Perl中引用和打印2D数组,arrays,perl,reference,Arrays,Perl,Reference,我一直在读关于如何在Perl中不能有数组的文章,因此我最终在数组引用方面遇到了困难,我想我找到了如何从子例程返回数组的方法。但是我不能让它在返回后打印整个数组。有人能告诉我为什么或者如何调试这个问题吗?真的非常感谢 #!/usr/bin/perl use strict; use warnings; #Subroutine to randomize the 2D Array: sub randPattern { my ($rand_ref) = @_; my @RandBoard = @$ran

我一直在读关于如何在Perl中不能有数组的文章,因此我最终在数组引用方面遇到了困难,我想我找到了如何从子例程返回数组的方法。但是我不能让它在返回后打印整个数组。有人能告诉我为什么或者如何调试这个问题吗?真的非常感谢

#!/usr/bin/perl
use strict;
use warnings;

#Subroutine to randomize the 2D Array:
sub randPattern {
my ($rand_ref) = @_;
my @RandBoard = @$rand_ref;

for (my $i = 0; $i <= $#RandBoard; $i++) {
  for (my $j = 0; $j <= $#RandBoard ; $j++) {
     $RandBoard[$i][$j] = 0 + int(rand(3 - 0));
     print "$RandBoard[$i][$j] ";
   }
   print "\n";
  }

return @RandBoard;
}

my @checkerArr =  (
  [0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0]
);

my ($randomizedArr_ref) = randPattern(\@checkerArr); #sending arrayy as reference
my @randomizedArr = @$randomizedArr_ref; #dereferencing the returned array
print "___________________\n";

foreach (@randomizedArr){
print "$_ "; }
print "\n";

正如您所见,它只输出数组的第一行。

首先,让我修复您的代码,然后我将解释

#!/usr/bin/perl
use strict;
use warnings;

#Subroutine to randomize the 2D Array:
sub randPattern {
my ($rand_ref) = $_[0];
my @RandBoard = @$rand_ref;

for (my $i = 0; $i <= $#RandBoard; $i++) {
  for (my $j = 0; $j <= $#{$RandBoard[$i]} ; $j++) {
     $RandBoard[$i][$j] = 0 + int(rand(3 - 0));
     print "$RandBoard[$i][$j] ";
   }
   print "\n";
  }

return @RandBoard;
}

my @checkerArr =  (
  [0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0]
);

my ($randomizedArr_ref) = [randPattern(\@checkerArr)]; #sending arrayy as reference
my @randomizedArr = @$randomizedArr_ref; #dereferencing the returned array
print "___________________\n";

foreach (@randomizedArr){
    print(join(' ',@$_),"\n");
}
这里的主要问题是标量上下文与列表上下文。您正在从子例程返回一个列表,并在标量上下文$randomizedArr_ref中分配该返回的列表。您得到的数组引用实际上是外部数组的最后一个元素。您需要在列表上下文中评估方法的返回,因此我在方法调用[randPattern\@checkerr]周围添加了方括号

我还将@u0更改为$0[0]来设置子例程中的参数,这是一个类似的疏忽。之所以只获取whlole参数,是因为您向数组传递了单个标量引用

哦,在你的循环中,我添加了一个数组的解引用,并加入了一个空格。我还将新行移动到循环中


更新:发现我忽略的另一个错误。在内部for循环中测试的内部数组的大小使用了碰巧相同的外部数组的大小。因此,我更改了内部for循环,以使用${$RandBoard[$I]}获得内部数组的大小。

我认为您在某种程度上过于复杂了

Perl确实做2D数组,您正确地认为它的实现是通过引用实现的

了解Data::Dumper对于打印复杂数据结构的内容非常方便可能会很有用

你的问题的核心在于这两个问题是如何相互联系的:

return @RandBoard;
这将返回多个值

但这只“使用”了其中一个,而丢弃了其余的:

my ($randomizedArr_ref) = randPattern(\@checkerArr);
因此,您“捕获”的只是对第一行的引用,然后打印它。如果您要尝试:

my ( @results ) = randPattern(\@checkerArr);
然后你会更接近,但我建议简单的解决方案是:

return \@RandBoard;
返回整个数据结构作为引用:

foreach my $row ( @$randomizedArr_ref ) {
    print join " ", @$row; 
}
使您的代码如下所示:

1 1 1 1 1 0 2 1 
1 0 0 0 2 2 0 1 
2 1 1 2 1 2 0 1 
1 2 0 2 0 1 0 1 
1 2 1 2 0 0 1 0 
2 1 0 1 0 0 0 2 
2 2 0 0 0 2 0 0 
1 1 1 0 0 1 1 1 
___________________
1 1 1 1 1 0 2 1 
#!/usr/bin/env perl
use strict;
use warnings;


#Subroutine to randomize the 2D Array:
sub randPattern {
   my ($rand_ref) = @_;
   my @RandBoard = @$rand_ref;

   for ( my $i = 0; $i <= $#RandBoard; $i++ ) {
      for ( my $j = 0; $j <= $#RandBoard; $j++ ) {
         $RandBoard[$i][$j] = 0 + int( rand( 3 - 0 ) );
         print "$RandBoard[$i][$j] ";
      }
      print "\n";
   }

   return \@RandBoard;
}

my @checkerArr = (
   [ 0, 0, 0, 0, 0, 0, 0, 0 ],
   [ 0, 0, 0, 0, 0, 0, 0, 0 ],
   [ 0, 0, 0, 0, 0, 0, 0, 0 ],
   [ 0, 0, 0, 0, 0, 0, 0, 0 ],
   [ 0, 0, 0, 0, 0, 0, 0, 0 ],
   [ 0, 0, 0, 0, 0, 0, 0, 0 ],
   [ 0, 0, 0, 0, 0, 0, 0, 0 ],
   [ 0, 0, 0, 0, 0, 0, 0, 0 ]
);

my ($randomizedArr_ref) =
  randPattern( \@checkerArr );    #sending arrayy as reference


print "____\n";
foreach my $row (@$randomizedArr_ref) {
   print join " ", @$row, "\n";
}
或者只是:

my @checkerArr = map { 
                        [ 
                            map { int rand(3) } (1..8) #array of 8 random values
                        ] 
                     } (1..8); #8 rows. 

此外,实际上可以将其简化很多。有些人可能会反对这样使用map以提高可读性,但我倾向于使用较少的代码:printjoin\n、map{join、map{intrand3}1..8}1..8、\n。这就是你的全部计划。你也可以用0x8初始化一个80的数组。可能是因为我错过了一些小东西而投了反对票,但我已经做了更新来修复它们。注意,我尽量保持大部分代码的原样,这样就不会有太多的更改,答案将集中在主要问题上。您将错误留在内部for循环中,他在外部数组$RandBoard的大小上循环。
my @checkerArr = map { 
                        [ 
                            map { int rand(3) } (1..8) #array of 8 random values
                        ] 
                     } (1..8); #8 rows.