documents:perl:perl-014
map関数とgrep関数の覚書
2016/03/27
ループをゴリゴリ書かないで済ますため雛型用に記録します。
map関数
map関数使用例 |
---|
実行結果 $ perl map.pl ex 1 : 2, 4, 6, 8, 10 ex 2 : 0.5, 1, 1.5, 2, 2.5 ex 3 : B, E, C, A, D $ |
map関数に与える配列の各要素に計算(ex1, ex2)を行い結果をリストで返します。
結果がいらないなら各要素毎に何か処理(ex 3)を行わせるためだけに使う事もできます。
grep関数
grep関数使用例 |
---|
実行結果 $ perl grep.pl ex 1 : 1, 2, 4, 5, 2, 4 ex 2 : 1, 3, 5 ex 3 : 3, 5, 6 ex 4 : orange, grape $ |
grep関数に与える配列の各要素に判定処理(ex1, ex2)を行い結果が真なら要素をリストで返します。
判定処理は何か処理(ex 3)でも構わないし、配列が文字列であれば正規表現(ex 4)を適用する事もできます。
map,grep関数応用
配列Aの重複要素を排除
- samle1.pl
$ cat sample1.pl use strict; my @aryA = ( "radish", "banana", "orange", "apple", "ginger", "banana", "strawberry", "grape", "apple" ); my $str0; my $str1; ## 配列A $str0 = join(", ", @aryA); ## 配列Aから重複排除 { my %ans; map( { $ans{$_}=0 } @aryA ); $str1 = join(", ", keys(%ans) ); } print "0:$str0\n"; print "1:$str1\n";
実行結果
$ perl sample1.pl 0:radish, banana, orange, apple, ginger, banana, strawberry, grape, apple 1:grape, orange, strawberry, banana, radish, apple, ginger $
配列Aの要素をハッシュのキーにして重複を消します。map関数をループ処理の代替としています。
処理 | map関数の時 |
---|---|
my %ans; foreach ( @aryA ) { $ans{$_}=0; } @ans = keys(%ans); | my %ans; map( { $ans{$_}=0 } @aryA ); @ans = keys(%ans); |
このくらいだとforeachを1行で書いてしまえばいいので微妙かな。
配列Bの要素を配列Aから削除
- sample2.pl
use strict; my @aryA = ( "radish", "banana", "orange", "apple", "ginger", "banana", "strawberry", "grape", "apple" ); my @aryB = ( "radish", "ginger", "potato" ); my $str0; my $str1; ## 配列A $str0 = join(", ", @aryA); ## 配列Aから配列Bの要素排除 { my %ex = map( ($_=>0) , @aryB ); my @ans = grep( !exists($ex{$_}), @aryA ); $str1 = join(", ", @ans ); } print "0:$str0\n"; print "1:$str1\n";
実行結果
$ perl sample2.pl 0:radish, banana, orange, apple, ginger, banana, strawberry, grape, apple 1:banana, orange, apple, banana, strawberry, grape, apple $
配列Bの要素をハッシュのキーにして、配列Aの要素がハッシュのキーとして存在するか否かで排除有無を判定しています。
処理 | map,grep関数組み合わせ |
---|---|
my %ex; my @ans; foreach (@aryB) { $ex{$_}=0; } foreach (@aryA) { if (!exists($ex{$_})) { push(@ans, $_); } } | my %ex = map( ($_=>0) , @aryB ); my @ans = grep( !exists($ex{$_}), @aryA ); |
まだこのくらいならどちらでも意図は伝わりそう。
重複要素と配列Bの要素を配列Aから削除
map関数 | grep関数 |
---|---|
|
|
実行結果
sample3.pl | sample4.pl |
---|---|
$ perl sample3.pl 0:radish , banana , orange , apple , ginger , banana , strawberry , grape , apple 1:banana , strawberry , apple , grape , orange $ | $ perl sample4.pl 0:radish , banana , orange , apple , ginger , banana , strawberry , grape , apple 1:banana , orange , apple , strawberry , grape $ |
関数なのに関数として使っていない例ばっかりで……
処理 | map関数処理 | grep関数処理 |
---|---|---|
my %ans; foreach ( @aryA) { $ans{$_}=0; } foreach (@aryB) { delete($ans{$_}); } @ans = keys(%ans); | my @ans; my %ans = map( ($_=>0), @aryA ); map( { delete($ans{$_}) } @aryB ); @ans = keys(%ans); | my %wk; my @ans; my %ex = map( ($_=>0), @aryB ); @ans = grep( !$wk{$_}++, @aryA ); @ans = grep( !exists($ex{$_}), @ans ); |
map関数+ハッシュの組み合わせでも、grep関数+ハッシュの組み合わせでも実現できます。処理の意味合いによってどちらを使うか考えてみるのが良いかなと思います。 grep関数を使う場合は、要素の並びが変わらないので、できるだけ並びを維持したいときはgrep関数が良いかもしれません。
documents/perl/perl-014.txt · 最終更新: 2024/11/01 16:30 by k896951