連想配列からキー/値ペアを取り出す
each
関数は while
構文などで連想配列のキーと値を順次取り出す際に利用します。
リストコンテキスト (戻り値をリストで受け取る状況) においては、
連想配列を引数に与えると、その連想配列内のキーと値から成るリストを返します。
my %hash = (
taro => 23,
jiro => 21,
saburo => 18
);
while ( my ( $key, $value ) = each %hash ) {
print "${key}: ${value}\n";
}
上記コードの出力結果は次のようになります。
saburo: 18
taro: 23
jiro: 21
スカラーコンテキスト (戻り値をスカラーで受け取る状況) においては、その連想配列内のキーだけを返します。
while ( my $key = each %hash ) {
print "${key}\n";
}
上記コードの出力結果は次のようになります。
saburo
jiro
taro
なお、連想配列を引数に与えた場合、each
によって取り出される要素の順番は保証されませんので注意してください。
取り出される順番はランダムです。そして、順番を決定するアルゴリズムも Perl のバージョンによって変わる可能性もあります。
そのため、決して each
によって取り出される要素の順番に期待しないようにしてください。
Perl 5.12 以降では、引数に配列を与えることもできます。その場合、その配列内の要素のインデックス番号と値を返します。 Perl 5.12 より前のバージョンで引数に配列を与えるとエラーになりますので注意してください。
my @array = ( 'taro', 'jiro', 'saburo' );
while ( my ( $index, $value ) = each @array ) {
print "${index}: ${value}\n";
}
上記コードの出力結果は次のようになります。
0: taro
1: jiro
2: saburo
基本的に、each
で連想配列の要素を順次取り出している途中で、その連想配列に要素を追加したり削除したりしないでください。
本来取り出されるべき要素が取り出されなかったり、逆に同じ要素が重複して取り出されてしまうかもしれません。
ただし、each
で取り出した直後にその要素を削除する場合は安全です。
while ( my ( $key, $value ) = each %hash ) {
print "${key}: ${value}\n";
delete $hash{$key}; # この削除は安全です
}
Perl 5.18 以降であれば、次のように each
の戻り値を受け取らない短い書き方も許されます。
while ( each %hash ) {
print "$_\n";
}
このコードは、実際には each
の戻り値を受け取らないわけではなく、
暗黙的にスカラー変数 $_ で受け取っています。