リストの値を編集して新たなリストを返す
map
は、LIST の各要素に対して BLOCK または EXPR に指定された処理を行い、
その結果を新たなリストとして返します。
次のサンプルコードは、配列 @names の各要素の値の先頭の文字を大文字に変換します。
my @names = ( 'taro', 'jiro', 'saburo' );
my @names2 = map ucfirst, @names;
print join( ', ', @names2 ); # Taro, Jiro, Saburo
上記のサンプルコードはかなり省略して記述しているため、Perl 初心者にとっては分かりづらいでしょう。 丁寧に書き換えると、次のような処理を行っています。
my @names2 = map { ucfirst $_ } @names;
各要素を処理する際には $_ が引き渡されますので、それを使って何かしらの変換処理を表現します。
変換処理の表現を中カッコ { } で囲んでいますが、これは関数(サブルーチン)ではありませんので、
この中カッコの中で return
は使えません。
中カッコの中では、変換後の値を表す式を記述します。
map
の BLOCK には、簡単な条件式を入れえることもできます。
次のサンプルは、奇数の場合のみ二乗します。
得られる新たな配列の要素数が、元の配列の要素数と違う点に注意してください。
my @numbers = ( 1, 2, 3, 4 );
my @squares = map { $_ % 2 ? ( $_ * $_ ) : () } @numbers;
print join( ', ', @squares ); # 1, 9
map
を使うと、配列から連想配列を生成することもできます。
次のサンプルは、名前が格納された配列から、その文字数を値に持つ連想配列を生成します。
my @names = ( 'taro', 'jiro', 'saburo' );
my %hash = map { $_ => length $_ } @names;
%hash には次のようなデータが格納されます。
(
'saburo' => 6,
'taro' => 4,
'jiro' => 4
)
BLOCK では配列の要素の値が $_ で表現されますが、この $_ の値を直接変更してしまうと、 元の配列の要素の値を編集することになってしまいますので注意してください。
my @numbers = ( 1, 2, 3 );
my @double = map { $_ = $_ * 2 } @numbers; # 元の配列の要素の値を編集してしまう
print join( ', ', @double ), "\n"; # 2, 4, 6
print join( ', ', @numbers ), "\n"; # 2, 4, 6