私は2つの配列を持っています:
@arr1 = ( 1, 0, 0, 0, 1 );
@arr2 = ( 1, 1, 0, 1, 1 );
両方の配列の項目を合計して、次のような新しいものを取得したい
( 2, 1, 0, 1, 2 );
配列をループせずにそれを行うことはできますか?
私は2つの配列を持っています:
@arr1 = ( 1, 0, 0, 0, 1 );
@arr2 = ( 1, 1, 0, 1, 1 );
両方の配列の項目を合計して、次のような新しいものを取得したい
( 2, 1, 0, 1, 2 );
配列をループせずにそれを行うことはできますか?
Perl 5 の場合:
use List::MoreUtils 'pairwise';
@sum = pairwise { $a + $b } @arr1, @arr2;
基本的に、いいえ、「配列をループ」せずにそれを行うことはできません。それらを合計するには、両方の配列のすべての要素にアクセスする必要があるためです。これまでの両方の答えは、ループを抽象化のレイヤーの下に隠しているだけですが、まだそこにあります。
非常に大きな配列をループすることが心配な場合は、合計を最新の状態に保つ他の方法を検討することをお勧めします。
Perl 6 を使用している場合:
@a = (1 0 0 0 1) <<+>> (1 1 0 1 1) #NB: the arrays need to be the same size
Perl 6 Advent Calendarには、さらに多くの例があります。
配列をループすることの何が問題になっていますか? それが基本です。
@arr1 = ( 1, 0, 0, 0, 1 );
@arr2 = ( 1, 1, 0, 1, 1 );
for ($i=0;$i<scalar @arr1;$i++){
print $arr[$i] + $arr2[$i] ."\n";
}
あなたはループのCスタイルを見てきました、そしてpairwise
。これが慣用的なPerlforループmap
です。
my @arr1 = ( 1, 0, 0, 0, 1 );
my @arr2 = ( 1, 1, 0, 1, 1 );
my @for_loop;
for my $i ( 0..$#arr1 ) {
push @for_loop, $arr1[$i] + $arr2[$i];
}
my @map_array = map { $arr1[$_] + $arr2[$_] } 0..$#arr1;
私は好きmap
でpairwise
最高です。これらの2つのオプションのどちらを優先するかはわかりません。 pairwise
配管の退屈な詳細を処理しますが、のような組み込みではありませんmap
。一方、マップソリューションは非常に慣用的であり、パートタイムのパーラーには不透明な場合があります。
したがって、どちらのアプローチでも実際の勝利はありません。IMO、両方pairwise
とmap
も良いです。
ループが本当に怖い場合は、配列をバイナリ チョップし、ペアを合計してから、結果の配列を再帰的に再構築できます。ループはありません。おまけとして、高速フーリエ変換の導出の一部がどのように機能するかを学ぶことができます。
(明示的な)ループを回避するために、「代わりに」再帰を使用するソリューションを次に示します。
#!/usr/bin/perl
use v5.20;
my @arr1 = ( 1, 0, 0, 0, 1 );
my @arr2 = ( 1, 1, 0, 1, 1 );
my @result=non_looping_pairwise_sum([ @arr1 ], [ @arr2 ]); # pass in copies, so the originals are not modified
say "@result";
sub non_looping_pairwise_sum { # only handles lists that have the same length
my ($a1, $a2)=@_;
return () if (scalar(@$a1)==0 and scalar(@$a2)==0);
my $e1=shift @$a1;
my $e2=shift @$a2;
return ($e1+$e2, non_looping_pairwise_sum($a1, $a2));
}
出力:
2 1 0 1 2
use v5.20
を書く必要がないことを意味することに注意してくださいuse strict; use warnings
。
アイデアに対する@parmへの謝罪/称賛。