documents:proglang:perl:perl-014
差分
このページの2つのバージョン間の差分を表示します。
| 両方とも前のリビジョン前のリビジョン | |||
| documents:proglang:perl:perl-014 [2026/05/08 11:54] – ↷ documents:perl:perl-014 から documents:proglang:perl:perl-014 へページを移動しました。 k896951 | documents:proglang:perl:perl-014 [2026/05/17 14:58] (現在) – k896951 | ||
|---|---|---|---|
| 行 1: | 行 1: | ||
| + | ====== 001.map関数とgrep関数の覚書 ====== | ||
| + | 2016/ | ||
| + | ループをゴリゴリ書かないで済ますため雛型用に記録します。 | ||
| + | |||
| + | ===== map関数 ===== | ||
| + | |||
| + | ^ map関数使用例 ^ | ||
| + | |<code perl map.pl> | ||
| + | use strict; | ||
| + | |||
| + | my @data = ( 1, 2, 3, 4, 5 ); | ||
| + | my %hash = ( 1=>" | ||
| + | my @ans1; | ||
| + | my @ans2; | ||
| + | |||
| + | sub func | ||
| + | { | ||
| + | my ($arg) = @_; | ||
| + | |||
| + | return $arg / 2; | ||
| + | } | ||
| + | |||
| + | @ans1 = map( $_ * 2 , @data ); ## exsample 1 | ||
| + | @ans2 = map( func($_) , @data ); ## exsample 2 | ||
| + | map( { $hash{$_}=uc($hash{$_}) } @data ); ## exsample 3 | ||
| + | |||
| + | print "ex 1 : " . join(", | ||
| + | print "ex 2 : " . join(", | ||
| + | print "ex 3 : " . join(", | ||
| + | </ | ||
| + | $ 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, | ||
| + | 結果がいらないなら各要素毎に何か処理(ex 3)を行わせるためだけに使う事もできます。 | ||
| + | |||
| + | ===== grep関数 ===== | ||
| + | |||
| + | ^ grep関数使用例 ^ | ||
| + | |<code perl grep.pl> | ||
| + | use strict; | ||
| + | |||
| + | my @data1 = ( 1, 2, 3, 4, 5, 2, 4, 6 ); | ||
| + | my @data2 = ( " | ||
| + | my @ans1; | ||
| + | my @ans2; | ||
| + | my @ans3; | ||
| + | my @ans4; | ||
| + | |||
| + | sub func | ||
| + | { | ||
| + | my ($arg) = @_; | ||
| + | |||
| + | return $arg % 2; | ||
| + | } | ||
| + | |||
| + | ## main | ||
| + | |||
| + | @ans1 = grep( $_ % 3 , | ||
| + | @ans2 = grep( func($_) , @data1 ); ## exsample 2 | ||
| + | @ans3 = grep( { 1 if (($_==3)||($_==5)||($_==6)) } @data1 ); ## exsample 3 | ||
| + | @ans4 = grep( / | ||
| + | |||
| + | print "ex 1 : " . join(", | ||
| + | print "ex 2 : " . join(", | ||
| + | print "ex 3 : " . join(", | ||
| + | print "ex 4 : " . join(", | ||
| + | </ | ||
| + | $ 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, | ||
| + | 判定処理は何か処理(ex 3)でも構わないし、配列が文字列であれば正規表現(ex 4)を適用する事もできます。 | ||
| + | |||
| + | ===== map, | ||
| + | |||
| + | ==== 配列Aの重複要素を排除 ==== | ||
| + | |||
| + | <code perl samle1.pl> | ||
| + | $ cat sample1.pl | ||
| + | use strict; | ||
| + | |||
| + | my @aryA = ( " | ||
| + | " | ||
| + | " | ||
| + | my $str0; | ||
| + | my $str1; | ||
| + | |||
| + | ## 配列A | ||
| + | $str0 = join(", | ||
| + | |||
| + | ## 配列Aから重複排除 | ||
| + | { | ||
| + | my %ans; | ||
| + | map( { $ans{$_}=0 } @aryA ); | ||
| + | |||
| + | $str1 = join(", | ||
| + | } | ||
| + | |||
| + | print " | ||
| + | print " | ||
| + | </ | ||
| + | |||
| + | 実行結果 | ||
| + | < | ||
| + | $ perl sample1.pl | ||
| + | 0:radish, banana, orange, apple, ginger, banana, strawberry, grape, apple | ||
| + | 1:grape, orange, strawberry, banana, radish, apple, ginger | ||
| + | $ | ||
| + | </ | ||
| + | |||
| + | 配列Aの要素をハッシュのキーにして重複を消します。map関数をループ処理の代替としています。 | ||
| + | |||
| + | ^ 処理 | ||
| + | |<code perl> | ||
| + | my %ans; | ||
| + | foreach ( @aryA ) | ||
| + | { | ||
| + | $ans{$_}=0; | ||
| + | } | ||
| + | @ans = keys(%ans); | ||
| + | </ | ||
| + | my %ans; | ||
| + | map( { $ans{$_}=0 } @aryA ); | ||
| + | @ans = keys(%ans); | ||
| + | </ | ||
| + | |||
| + | このくらいだとforeachを1行で書いてしまえばいいので微妙かな。 | ||
| + | |||
| + | ==== 配列Bの要素を配列Aから削除 ==== | ||
| + | |||
| + | <code perl sample2.pl> | ||
| + | use strict; | ||
| + | |||
| + | my @aryA = ( " | ||
| + | " | ||
| + | " | ||
| + | my @aryB = ( " | ||
| + | my $str0; | ||
| + | my $str1; | ||
| + | |||
| + | ## 配列A | ||
| + | $str0 = join(", | ||
| + | |||
| + | ## 配列Aから配列Bの要素排除 | ||
| + | { | ||
| + | my %ex = map( ($_=>0) , @aryB ); | ||
| + | my @ans = grep( !exists($ex{$_}), | ||
| + | |||
| + | $str1 = join(", | ||
| + | } | ||
| + | |||
| + | print " | ||
| + | print " | ||
| + | </ | ||
| + | |||
| + | 実行結果 | ||
| + | < | ||
| + | $ perl sample2.pl | ||
| + | 0:radish, banana, orange, apple, ginger, banana, strawberry, grape, apple | ||
| + | 1:banana, orange, apple, banana, strawberry, grape, apple | ||
| + | $ | ||
| + | </ | ||
| + | |||
| + | 配列Bの要素をハッシュのキーにして、配列Aの要素がハッシュのキーとして存在するか否かで排除有無を判定しています。 | ||
| + | ^ 処理 | ||
| + | |<code perl> | ||
| + | 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{$_}), | ||
| + | </ | ||
| + | |||
| + | まだこのくらいならどちらでも意図は伝わりそう。 | ||
| + | |||
| + | ==== 重複要素と配列Bの要素を配列Aから削除 ==== | ||
| + | |||
| + | ^ map関数 | ||
| + | |<code perl sample3.pl> | ||
| + | use strict; | ||
| + | |||
| + | my @aryA = ( " | ||
| + | " | ||
| + | " | ||
| + | my @aryB = ( " | ||
| + | my $str0; | ||
| + | my $str1; | ||
| + | |||
| + | ## 配列A | ||
| + | $str0 = join(" , ", @aryA); | ||
| + | |||
| + | ## 配列Aから重複排除後に配列Bの要素を排除 | ||
| + | { | ||
| + | my %ans = map( ($_=> | ||
| + | map( { delete($ans{$_}) } @aryB ); | ||
| + | |||
| + | $str1 = join(" , ", keys(%ans) ); | ||
| + | } | ||
| + | |||
| + | print " | ||
| + | print " | ||
| + | </ | ||
| + | use strict; | ||
| + | |||
| + | my @aryA = ( " | ||
| + | " | ||
| + | " | ||
| + | my @aryB = ( " | ||
| + | my $str0; | ||
| + | my $str1; | ||
| + | |||
| + | ## 配列A | ||
| + | $str0 = join(" , ", @aryA); | ||
| + | |||
| + | ## 配列Aから重複排除後に配列Bの要素を排除 | ||
| + | { | ||
| + | my %wk; | ||
| + | my @ans; | ||
| + | my %ex = map( ($_=>0), @aryB ); | ||
| + | |||
| + | @ans = grep( !$wk{$_}++, | ||
| + | @ans = grep( !exists($ex{$_}), | ||
| + | |||
| + | $str1 = join(" , ", @ans ); | ||
| + | } | ||
| + | |||
| + | print " | ||
| + | print " | ||
| + | </ | ||
| + | |||
| + | 実行結果 | ||
| + | ^ sample3.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 | ||
| + | $ | ||
| + | </ | ||
| + | |||
| + | 関数なのに関数として使っていない例ばっかりで…… | ||
| + | |||
| + | ^ 処理 | ||
| + | |<code perl> | ||
| + | my %ans; | ||
| + | foreach ( @aryA) | ||
| + | { | ||
| + | $ans{$_}=0; | ||
| + | } | ||
| + | foreach (@aryB) | ||
| + | { | ||
| + | delete($ans{$_}); | ||
| + | } | ||
| + | @ans = keys(%ans); | ||
| + | </ | ||
| + | my @ans; | ||
| + | my %ans = map( ($_=> | ||
| + | map( { delete($ans{$_}) } @aryB ); | ||
| + | @ans = keys(%ans); | ||
| + | </ | ||
| + | my %wk; | ||
| + | my @ans; | ||
| + | my %ex = map( ($_=>0), @aryB ); | ||
| + | @ans = grep( !$wk{$_}++, | ||
| + | @ans = grep( !exists($ex{$_}), | ||
| + | </ | ||
| + | |||
| + | map関数+ハッシュの組み合わせでも、grep関数+ハッシュの組み合わせでも実現できます。処理の意味合いによってどちらを使うか考えてみるのが良いかなと思います。 | ||
| + | grep関数を使う場合は、要素の並びが変わらないので、できるだけ並びを維持したいときはgrep関数が良いかもしれません。 | ||
| + | |||
| + | {{tag> | ||
documents/proglang/perl/perl-014.txt · 最終更新: by k896951
