[perl] 配列の値から重複する値を除く(grep 利用)


何とか理解・・・配列から重複を取り除く

こういう処理って、結構使うけど面倒っだったりする。
軽くググッたらそれっぽいのがすぐに見つかったねー。perlすごい!
http://d.hatena.ne.jp/Leila/20090204/1233716119

【概要】
与えられた配列(tmp_arr)の値をキーにして出現した個数をバリューにする%hという一時ハッシュ変数を作りつつ、初めて出てきたキーは@arrに入れるってな感じの処理。


my @tmp_arr = (2, 3, 55, 2, 4, 2, 3, 5);
my @arr = do { my %h; grep { !$h{$_}++ } @tmp_arr };

@arrは 重複が除かれた[2, 3, 55, 4, 5]の配列となっている。

すごっ。
これを素直に書くと以下のようになるかな?

my @tmp_arr = (2, 3, 55, 2, 4, 2, 3, 5);
my @arr;
my %h;
for my $t (@tmp_arr) {
    if(!$h{$t}) {
        push @arr, $t;
        $h{$t}++;
    }
    else {
        $h{$t}++;
    }
}

そこで配列に2つ以上出て来た値を抽出するにはどうするんだろうっていう疑問

重複なしとほぼ同様に以下の様な感じになるかなぁー
tmp_arrの値をキーにして出現した個数をインクリメントした値をバリューとするハッシュ。
そのバリューの値が2となった時に配列の@arrへ追加する。

grepしているところで 2 のところを3とか4とかにすると3回以上,4回以上でた値を抽出出来る。

http://perl-users.jp/articles/advent-calendar/2008/16.html


my @tmp_arr = (2, 3, 55, 2, 4, 2, 3, 5);
my @arr = do { my %h; grep { ++$h{$_} == 2 } @tmp_arr };
                                         ~~
@arrは [2, 3]の配列となっている。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です