[Perl]grepとmap

配列を操作するgrepとmapがとても便利なのですが、脳内で結構くちゃくちゃになりがちなのでメモしておきます。
単体で使用する場合はそれほどでもないのですが、多次元配列で使用したり組み合わせて使ったりするので混乱しやすいのです。

 

単純に言ってしまうと…
grepは配列を絞り込んだものを返します。
mapは、配列を操作したものを返します。ブレス括弧内で最後に評価された値が各要素となります。

my @array = ( 1, 2, 3, 4 );
my @grep_array = grep { $_ <= 2 } @grep_array;
# @grep_array = ( 1, 2 );

my @map_array = map { $_+2 } @array;
# @map_array = ( 3, 4, 5, 6 );

my @grep_map_array = map { $_+2 } grep { $_ <= 2 } @array;
# @grep_map_array = ( 3, 4 );

my @map_grep_array = grep { $_ <= 3 } map { $_ + 2 } @array;
# @map_grep_array = ( 3 );

連想配列をいじる場合はkeysで。でも、これはあまり使用しない気がします。

ハッシュの配列のほうがよく使います。

my $nested = [
  { domain => 'saruzie.com', port => 443, protocol => 'https' }
  , { domain => 'waruzie.com', port => 80, protocol => 'http' }
];

my $grep = [];
@{$grep} = grep { $_->{port} == 443 } @{$nested};
# $grep = [
#   { domain => 'saruzie.com', port => 443, protocol => 'https' }
# ]

my $map = [];
@{$map} = map { my $tmp = { port => 80, protocol => 'http', domain => $_->{domain} }; $tmp; } @{$nested};
# $map = [
#   { domain => 'saruzie.com', port => 80, protocol => 'http' }
#   , { domain => 'waruzie.com', port => 80, protocol => 'http' }
# ]

最後の多次元配列のmapは、foreachとpush使ったほうが読みやすいですね。

my $nested = [
  { domain => 'saruzie.com', port => 443, protocol => 'https' }
  , { domain => 'waruzie.com', port => 80, protocol => 'http' }
];
my $map = [];
my $tmp = {};
foreach( @{$nested} ){
  $tmp = {
    port => 80
    , protocol => 'http';
    , domain => $_->{domain}
  };
  push @{$map}, $tmp;
}

# $map = [
#   { domain => 'saruzie.com', port => 80, protocol => 'http' }
#   , { domain => 'waruzie.com', port => 80, protocol => 'http' }
# ]

とりあえず簡単な例ですが、使いどころがかなりたくさんありますので、とりあえずメモでした。

© 2018- Saruzie.