「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
。
簡単なテスト:
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];
\@
または+
プロトタイプを使用するのではなく、参照として配列を渡すことを好みます。これにより、次のことが可能になります。
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 ],
);