将ArrayRef解压缩为X个单独的参数

Hun*_*len 4 perl

给定一个包含其他arrayrefs的arrayref,是否可以使用zip函数将嵌套的arrayrefs压缩在一起List::MoreUtils

比如给出这个arrayref:

my $matrix = [
   [qw( 1  2  3  4)],
   [qw( 5  6  7  8)],
   [qw( 9 10 11 12)],
   [qw(13 14 15 16)],
   [qw(17 18 19 20)],
];
Run Code Online (Sandbox Code Playgroud)

我想将每一行压缩在一起,这样我就可以进行转置.预期产量:

[
   [qw(1 5  9 13 17)],
   [qw(2 6 10 14 18)],
   [qw(3 7 11 15 19)],
   [qw(4 8 12 16 20)],
];
Run Code Online (Sandbox Code Playgroud)

我最初的尝试是:

# I had hoped the function would unpack the arguments
zip @$matrix; 
# ERROR: Not enough arguments for List::MoreUtils::mesh at spiral.pl line 17

# I thought this slice would suffice to unpack them
zip @$matrix[1..scalar @$matrix-1]; 
# ERROR: Type of arg 1 to List::MoreUtils::mesh must be array (not array slice)
Run Code Online (Sandbox Code Playgroud)

我确信有一种方法可以优雅地做到这一点,我只是没有看到它.任何帮助,将不胜感激.

amo*_*mon 6

zip功能是非常讨厌的,因为它使用一个(\@\@;\@\@\@...)原型或疯狂的东西类似的.你必须做一个&符号来覆盖原型:&zip(@$matrix).

但是,你试图转置矩阵,而不是zip它(它会生成一个连续的列表,如

[1, 5, 9, 13, 17, 2, 6, 10, 14, 18, 3, 7, 11, 15, 19, 4, 8, 12, 16, 20]
Run Code Online (Sandbox Code Playgroud)

我们可以natatime结合使用迭代器zip:

my $iter = natatime @$matrix, &zip(@$matrix);
my @transposed;
while (my @column = $iter->()) {
    push @transposed, \@column;
}
Run Code Online (Sandbox Code Playgroud)

哪个有效,但这严重地过分了问题.我们只是交换指数:

my $transposed = [];
for my $i (0 .. $#$matrix) {
    for my $j (0 .. $#{ $matrix->[0] }) {
        $transposed->[$j][$i] = $matrix->[$i][$j];
    }
}
Run Code Online (Sandbox Code Playgroud)