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

时间:2016-11-17 20:48:24

标签: arrays perl reference

我一直在阅读你如何在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";

输出如下:

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 

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

2 个答案:

答案 0 :(得分:0)

我认为你有点过于复杂。

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

使你的代码像这样:

#!/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";
}

但实际上你可以大规模简化你的代码:

foreach my $row ( @checkerArr ) { 
    $_ = int rand(3) for @$row; 
}

或者只是:

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

答案 1 :(得分:-1)

首先,让我修复你的代码,然后我会解释......

#!/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)。你得到一个数组引用(实际上是外部数组的 last 元素。你需要在列表上下文中评估方法的返回,所以我在方法调用周围添加了方括号({ {1}})。

我还将[randPattern(\@checkerArr)]更改为@_到子程序中参数的设置,这是类似的疏忽。你只获得whlole参数,因为你传入一个标量(引用数组)。

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

更新:发现了我忽略的另一个错误。在内部for循环中测试的内部数组的大小是使用外部数组的大小(碰巧是相同的)。所以我更改了内部for循环以获得内部数组的大小为$_[0]