您可以轻松实现“n-wise”函数:
sub nwise (&@) # ← take a code block, and any number of further arguments
{
my ($code, @arefs) = @_;
return map {$code->( do{ my $i = $_; map $arefs[$_][$i], 0 .. $#arefs } )}
0 .. $#{$arefs[0]};
}
该代码有点难看,因为 Perl 不支持多维数组的切片。相反,我使用嵌套map
的 s。
快速测试:
use Test::More;
my @a = (1, 0, 0, 0, 1);
my @b = (1, 1, 0, 1, 1);
my @c = (2, 0, 2, 1, 0);
is_deeply [ nwise { $_[0] + $_[1] + $_[2] } \@a, \@b, \@c], [4, 1, 2, 2, 2];
我更喜欢将数组作为引用传递,而不是使用\@
or+
原型:这允许你做
my @arrays = (\@a, \@b, \@c);
nwise {...} @arrays;
从List::MoreUtils
你也可以使用each_arrayref
:
use List::Util qw/sum/;
use List::MoreUtils qw/each_arrayref/;
my $iter = each_arrayref @arrays;
my @out;
while (my @vals = $iter->()) {
push @out, sum @vals;
}
is_deeply \@out, [4, 1, 2, 2, 2];
或者只是简单的旧循环:
my @out;
for my $i (0 .. $#a) {
my $accumulator = 0;
for my $array (@arrays) {
$accumulator += $array->[$i];
}
push @out, $accumulator;
}
is_deeply \@out, [4, 1, 2, 2, 2];
以上都假设所有数组的长度相同。
关于您的片段的注释:
您的数组结构示例当然是合法的 perl,它甚至可以按预期运行,但最好省略内部分配:
my @AoA = (
[ 1, 0, 0, 0, 1 ],
[ 1, 1, 0, 1, 1 ],
[ 2, 0, 2, 1, 0 ],
);