Building and printing a multidimensional list in Perl without looping

让人想犯罪 __ 提交于 2020-01-03 04:35:42

问题


The top answer in this post: How can I create a multidimensional array in Perl? suggests building a multi-dimensional array as follows:

my @array = ();
foreach my $i ( 0 .. 10 ) {
  foreach my $j ( 0 .. 10 ) {
    push @{ $array[$i] }, $j;
  }
}

I am wondering if there is a way of building the array more compactly and avoiding the nested loop, e.g. using something like:

my @array = ();
my @other_array = (0 ... 10);
foreach my $i ( 0 .. 10 ) {
    $array[$i] = @other_array; # This does not work in Perl
  }
}

Does Perl support any syntax like that for building multi-dimensional arrays without nested looping?

Similarly, is there a way to print the multidimensional array without (nested) looping?


回答1:


There is more than one way to do it:

Generating

push accepts LISTs

my @array;
push @{$array[$_]}, 0 .. 10 for 0 .. 10;

Alternative syntax:

my @array;
push @array, [ 0 .. 10 ] for 0 .. 10;

map eye-candy

my @array = map { [ 0 .. 10 ] } 0 .. 10;

Alternative syntax:

my @array = map [ 0 .. 10 ], 0 .. 10;

Printing

With minimal looping

print "@$_\n" for @array;

On Perl 5.10+

use feature 'say';
say "@$_" for @array;

With more formatting control

print join( ', ', @$_ ), "\n" for @array;   # "0, 1, 2, ... 9, 10"

"No loops" (The loop is hidden from you)

use Data::Dump 'dd';
dd @array;

Data::Dumper

use Data::Dumper;
print Dumper \@array;

Have a look at perldoc perllol for more details




回答2:


You are close, you need a reference to the other array

my @array;  # don't need the empty list
my @other_array = (0 ... 10);
foreach my $i ( 0 .. 10 ) {
    $array[$i] = \@other_array;
    # or without a connection to the original
    $array[$i] = [ @other_array ];
    # or for a slice
    $array[$i] = [ @other_array[1..$#other_array] ];
  }
}

You can also make anonymous (unnamed) array reference directly using square braces [] around a list.

my @array;
foreach my $i ( 0 .. 10 ) {
    $array[$i] = [0..10];
  }
}

Edit: printing is probably easiest using the postfix for

print "@$_\n" for @array;

for numerical multidimensional arrays, you can use PDL. It has several constructors for different use cases. The one analogous to the above would be xvals. Note that PDL objects overload printing, so you can just print them out.

use PDL;
my $pdl = xvals(11, 11);
print $pdl;


来源:https://stackoverflow.com/questions/12392127/building-and-printing-a-multidimensional-list-in-perl-without-looping

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!