スキームでは、次のように複数のリストを反復処理できますfor-each
。
> (for-each (lambda (a b) (display (+ a b)) (newline)) '(10 20 30) '(1 2 3))
11
22
33
>
for
Perl では、単一のリストを反復処理するために使用できることを知っています。スキームの例のように、複数のリストを反復する良い方法は何ですか?
Perl 5 または 6 の回答に興味があります。
Perl 6 では、Zip 演算子が最適です。両方の値を取得したい (合計を直接計算したくない) 場合は、プラス記号なしで使用できます。
for (10, 11, 12) Z (1, 2, 3) -> $a, $b {
say "$a and $b";
}
Perl 5 では、モジュールList::MoreUtilsを使用できます。ペアごとに、または each_array によって返される反復子 (並列で反復処理するには 2 つ以上の配列が必要になる場合があります) を使用します。
use 5.12.0;
use List::MoreUtils qw(pairwise each_array);
my @one = qw(a b c d e);
my @two = qw(q w e r t);
my @three = pairwise {"$a:$b"} @one, @two;
say join(" ", @three);
my $it = each_array(@one, @two);
while (my @elems = $it->()) {
say "$elems[0] and $elems[1]";
}
Zip 演算子を使用すると、Scheme で行っていることを実現できます。
> .say for (10, 20, 30) Z+ (1, 2, 3)
11
22
33
同じサイズであることが確実な場合は、配列のインデックスを反復処理することができます。
foreach( 0 .. $#array1 ) {
print $array1[$_] + $array2[$_], "\n";
}
Algorithm::Loopsは、複数の配列を反復するための MapCar 関数を提供します (異なるサイズの配列を異なる方法で処理するバリアントを使用)。
As long as the question is as simple as just adding (/multiplying, dividing,…) and the Arrays are no Arrays of Arrays, you also could use the hyper-operators for your task:
<1 2 3> «+» <10 20 30>
(of course this is a Perl6 answer)
if you don't have access to the French quotes «»
, you could rewrite it as
<1 2 3> <<+>> <10 20 30>
1 つの方法は次のとおりです。
sub for_each
{
my $proc = shift ;
my $len = @{$_[0]} ;
for ( my $i = 0 ; $i < $len ; $i++ )
{
my @args = map $_->[$i] , @_ ;
&$proc ( @args ) ;
}
}
for_each sub { say $_[0] + $_[1] } , ([10,20,30],[1,2,3])
each_arrayref
からの使用List::MoreUtils
:
sub for_each
{
my $proc = shift ;
my $it = each_arrayref ( @_ ) ;
while ( my @elts = $it->() ) { &$proc ( @elts ) } ;
}
for_each sub { say $_[0] + $_[1] } , ([10,20,30],[1,2,3])
指摘してくれたアレックスに感謝しList::MoreUtils
ます。
解決策の 1 つ (選択肢は多数あります) は、次のようになります。
my @argle = (10, 20, 30);
my @bargle = (1, 2, 3);
do {
my $yin = shift @argle;
my $yang = shift @bargle;
say $yin + $yang;
} while (@argle && @bargle);
について質問しているように感じますforeach
。これは次のようになります。
my @argle = (10, 20, 30);
my @bargle = (1, 2, 3);
for my $yin (@argle) {
my $yang = shift @bargle;
say $yin + $yang;
}
しかし、この場合はそれほどスムーズではありません。どちらかの配列が短い場合はどうなりますか?