Perl:通过这个时髦的阵列迭代?

时间:2010-09-13 20:45:52

标签: arrays perl multidimensional-array

我正在尝试迭代以这种特定方式构建的2D数组。这是否是构造数组的好方法是另一个问题 - 我仍然需要能够迭代它(如果可能的话)。

@row1 = ( "Current Scan", "Last Month");
@row2 = ( "240", "0");
@row3 = ( "226", "209");
@row4 = ( "215", "207");

@array = (\@row1, \@row2, \@row3, \@row4);
print Dumper(@array);
printarray(@array);

Dumper给了我以下输出:

$VAR1 = [
          'Current Scan',
          'Last Month'
        ];
$VAR2 = [
          '240',
          '0'
        ];
$VAR3 = [
          '226',
          '209'
        ];
$VAR4 = [
          '215',
          '207'
        ];

我尝试了几个for循环但没有成功。每个只打印第一行($ VAR1)并退出。这是我最近的尝试:

sub printarray {
  @array = shift;
  $rowi = 0;
  foreach my $row (@array) {
    for (my $coli = 0; $coli <= @$row; $coli++) {
      print "$array[$rowi][$coli]\n";
    }
    $rowi++;
  }
}

我显然忽略了一些简单的事情。我究竟做错了什么?提前谢谢!

5 个答案:

答案 0 :(得分:10)

如果您只想打印数组,请尝试以下代码:

foreach my $row (@array) {
   foreach my $elem (@$row) {
       print $elem; ## print elements without separator
   }
   print "\n"; ## new line after row
}

如果您出于某种目的需要索引,请转到:

for(my $row_i = 0; $row_i < @array; $row_i++) {
    for(my $column_i = 0; $column_i < @{ $array[$row_i] }; $column_i++) {
        print $array[$row_i][$column_i];
    }
}

这个想法是标量上下文中的@array 返回数组中元素的数量。并且@{ $array[$row_i] }有点棘手。它取消引用存储在$array[$row_i]中的数组。

子程序更新:

在perl中,您可以通过引用传递数组:

 printarray(\@array); ## pass reference

 sub printarray {
     my $array_ref = shift; ## no copy created

     foreach my $row (@$array_ref) { ## now we need to dereference
         ...
     }
 }

您还可以传递数组副本:

 printarray(@array);

 sub printarray {
     my @array_copy = @_; ## store local copy of array
     ...
 }

有关详细信息,请查看How can I pass/return a {Function, FileHandle, Array, Hash, Method, Regex}?手册页。

请在程序开头添加 use strict; 。它会强制你声明所有变量,但是如果输入错误的话会节省大量时间。

答案 1 :(得分:3)

当你将数组传递给子程序时,你实际上传递了8个标量。然后,当你做

sub printarray {
  @array = shift;

...你只是弹出列表中的第一个元素。尝试:

sub printarray {
  @array = @_;

答案 2 :(得分:1)

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

   my @row1 = ( "Current Scan", "Last Month");
   my @row2 = ( "240", "0");
   my @row3 = ( "226", "209");
   my @row4 = ( "215", "207");

   my @array = (\@row1, \@row2, \@row3, \@row4);

   foreach my $row (@array) {
     foreach my $value (@$row) {
        print "$value\n";
     }
   }

这将打印

  Current Scan
  Last Month
  240
  0
  226
  209
  215
  207

不确定这是不是你想要的。

答案 3 :(得分:1)

是的,问题在于您将数组传递给子例程的方式。 Perl展平参数列表中的数组。基本上,printarray(@array)(在此示例中)等同于printarray($array[0], $array[1], $array[2], $array[3])shift开头的printarray获取第一个参数并将其分配给@array。因此,无论数组有多大,printarray只能看到第一个元素。

答案 4 :(得分:0)

你在寻找这样的东西:

#!/usr/bin/perl
use warnings;
use strict;
use Algorithm::Loops 'MapCar';

my @row1 = ( "Current Scan", "Last Month");
my @row2 = ( "240", "0");
my @row3 = ( "226", "209");
my @row4 = ( "215", "207");

my @array = (\@row1, \@row2, \@row3, \@row4);

MapCar { print "Scan: $_[0]: $_[1], $_[2], $_[3]\n" } @array;