简体   繁体   English

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

[英]Referencing and printing a 2D array in Perl

I've been reading about how you can't have an array of arrays in Perl thus I ended up struggling with references of arrays and I think I figure out how to return the array from a subroutine. 我一直在阅读有关如何在Perl中无法获得数组数组的信息,因此我最终陷入了数组引用的困境,我认为我想出了如何从子例程中返回数组。 However I can't get it to print the entire array after the return. 但是我不能让它在返回后打印整个数组。 Can someone explain to me why or how to debug this issue? 有人可以向我解释为什么或如何调试此问题吗? It would be really appreciated indeed! 的确将不胜感激!

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

And the output is like this: 输出是这样的:

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 

As you can see it only outputs the first row of the array. 如您所见,它仅输出数组的第一行。

I think you've overcomplicated it somewhat. 我认为您已经使它过于复杂了。

Perl does do 2D arrays, and you're correct in thinking the the implementation of that is via references. Perl确实可以进行2D数组处理,您认为通过引用来实现该数组是正确的。

It may be useful to know that Data::Dumper is really handy for printing the contents of a complex data structure. 了解Data::Dumper对于打印复杂数据结构的内容确实非常有用,可能会很有用。

The core of your problem is in how these two iteract: 您问题的核心在于这两个迭代的方式:

return @RandBoard;

this returns multiple values. 这将返回多个值。

But this only 'uses' one of them, and discards the rest: 但这仅“使用”其中一个,而丢弃其余的:

my ($randomizedArr_ref) = randPattern(\@checkerArr);

So what you're 'catching' is just the reference to the first line - and then printing it. 因此,您要“捕捉”的只是对第一行的引用-然后进行打印。 If you were to try: 如果您要尝试:

my ( @results ) = randPattern(\@checkerArr);

Then you'd come closer, but I'd suggest simple solution is: 然后您会更加接近,但是我建议简单的解决方案是:

return \@RandBoard;

Which returns the whole data structure as a reference: 它返回整个数据结构作为参考:

foreach my $row ( @$randomizedArr_ref ) {
    print join " ", @$row; 
}

Making your code like this: 使您的代码是这样的:

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

But actually you could simplify your code massively: 但是实际上您可以大量简化代码:

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

Or just: 要不就:

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

First, let me fix your code, then I'll explain... 首先,让我修复您的代码,然后再说明...

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

The main issue here is scalar context versus list context. 这里的主要问题是标量上下文与列表上下文。 You're returning a list from your subroutine and assigning that returned list in a scalar context ($randomizedArr_ref). 您将从子例程返回一个列表,并在标量上下文中分配该返回的列表($ randomizedArr_ref)。 You were getting an array reference (which was actually the last element of your outer array. You need to evaluate the return of the method in list context, so I added the square brackets around your method call ( [randPattern(\\@checkerArr)] ). 您正在获取数组引用(实际上是外部数组的最后一个元素。您需要在列表上下文中评估方法的返回值,因此我在方法调用的周围加上了方括号( [randPattern(\\@checkerArr)] )。

I also changed @_ to $_[0] to your setting of the parameter in the subroutine, which is a similar oversight. 我也将@_更改为$_[0]来设置子例程中的参数,这是类似的疏忽。 You were only getting the whlole parameter because you were passing in a single scalar (reference to an array). 您仅获得whlole参数,因为您传入的是单个标量(对数组的引用)。

Oh, and in your loop, I added a dereference of the array and joined with a space. 哦,在您的循环中,我添加了对该数组的取消引用,并添加了一个空格。 I also moved the newline into the loop. 我也将换行符移动到循环中。

UPDATE: Found another error I overlooked. 更新:发现另一个我忽略的错误。 The size of the inner array tested in the inner for loop was using the size of the outer array (which happened to be the same). 在内部for循环中测试的内部数组的大小使用外部数组的大小(碰巧是相同的)。 So I changed the inner for loop to get the size of the inner array with $#{$RandBoard[$i]} . 因此,我更改了内部for循环以使用$#{$RandBoard[$i]}获得内部数组的大小。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM