連想配列 は、文字列を キー とする配列です。ハッシュ とも呼ばれます。個々の要素は $連想配列名{キー} で表します。配列ではキー(添字)を [...] で囲みますが、連想配列では {...} で囲みます。
$person{'Name'} = "Tanaka"; $person{'Age'} = 26; $person{'Tel'} = "012-345-6789"; print "$person{'Name'} $person{'Age'} $person{'Tel'}\n";
実行結果は次のようになります。
Tanaka 26 012-345-6789
連想配列全体を %連想配列名 で表します。Perl 5では、上記のようにして、連想配列の各要素を一度に代入できるようになりました。
%person = ( Name => "Tanaka", Age => 26, Tel => "012-3456-7890" ); print "$person{'Name'} $person{'Age'} $person{'Tel'}\n";
Perl 4 では次のようにして一括代入が可能です。
%person = ( "Name", "Tanaka", "Age", 26, "Tel", "012-3456-7890" );
下記のようにして、連想配列 %data1 と連想配列 %data2 を連結して、新しい連想配列 %data3 を生成することができます。
%data1 = ( "AAA" => "aaa", "BBB" => "bbb", "CCC" => "ccc" ); %data2 = ( "XXX" => "xxx", "YYY" => "yyy", "ZZZ" => "zzz" ); %data3 = ( %data1, %data2 ); print "ZZZ = $data3{'ZZZ'}\n";
結果は次のようになります。
ZZZ = zzz
%data1 と %data2 の中に同じキーの値が存在する場合は、後ろに指定した連想配列の値が有効になります。
%data1 = ( "AAA" => "aaa", "BBB" => "bbb", "CCC" => "ccc" ); %data2 = ( "CCC" => "333", "DDD" => "444", "EEE" => "555" ); %data3 = ( %data1, %data2 ); print "CCC = $data3{'CCC'}\n";
結果は次のようになります。
CCC = 333
each() は、連想配列のキーと値の組みを返します。each() を用いて、連想配列の個々の要素に関して処理を行うことができます。
$data{'AAA'} = "aaa"; $data{'BBB'} = "bbb"; $data{'CCC'} = "ccc"; while (($key, $value) = each(%data)) { print "$key = $value\n"; }
表示結果は例えば次のようになります。
CCC = ccc BBB = bbb AAA = aaa
連想配列が処理される順番はデタラメです。代入した順序通りにはなりませんし、キーや値の ABC順になる訳でもありません。
each(%連想配列名) を用いた場合、順序はバラバラになります。代入した順序通りに処理したい時は、キーの配列を、連想配列とは別に用意する必要があります。
$n = 0; $data{'AAA'} = "xxx"; $keys[$n++] = "AAA"; $data{'BBB'} = "zzz"; $keys[$n++] = "BBB"; $data{'CCC'} = "yyy"; $keys[$n++] = "CCC"; foreach $key (@keys) { print "$key = $data{$key}\n"; }
結果は次のようになります。代入した順序通りに表示されます。
AAA = xxx BBB = zzz CCC = yyy
keys() は、連想配列のキーのみからなる配列を返します。これをソートして foreach で回すことにより、連想配列をキーの辞書順に処理することができます。
$data{'AAA'} = "xxx"; $data{'BBB'} = "zzz"; $data{'CCC'} = "yyy"; # キーでソートする foreach $key (sort keys(%data)) { print "$key = $data{$key}\n"; }
結果は次のようになります。
AAA = xxx BBB = zzz CCC = yyy
values() は、連想配列の値のみからなる配列を返します。これをソートして参照することにより、連想配列を値順に処理することができます。数値としてソートしたい場合は sort { $a <=> $b } values(%data) としてください。
$data{'AAA'} = "xxx"; $data{'BBB'} = "zzz"; $data{'CCC'} = "yyy"; # 値でソートする foreach $value (sort values(%data)) { print "$value\n"; }
結果は次のようになります。
xxx yyy zzz
値からキーを求めることはできないので、上の例では print "$key = $value\n"; のように記述することができません。これを実現するには次のようにします。
$data{'AAA'} = "xxx"; $data{'BBB'} = "zzz"; $data{'CCC'} = "yyy"; foreach $key (sort { $data{$a} cmp $data{$b} } keys(%data)) { print "$key = $data{$key}\n"; }
これを実行すると次のようになります。
AAA = xxx CCC = yyy BBB = zzz
ちょっと複雑ですが、keys(%data) でキーのみの配列を作成し、これを、キーの値で比較しながらソートし、ソートした結果について、foreach で順番に処理します。数値比較の場合は cmp を <=> に変更してください。
連想配列の各要素を削除するには、delete を用います。
$data{'AAA'} = "aaa"; $data{'BBB'} = "bbb"; $data{'CCC'} = "ccc"; delete($data{'BBB'}); # BBB の要素を削除する while (($key, $value) = each(%data)) { print "$key = $value\n"; }
結果は次のようになります。BBB が削除されているので、AAA と CCC のみが表示されます。
CCC = ccc AAA = aaa
連想配列全体を削除する(未定義状態にする)には、undef を用います。
undef(%data);
上記のように、連想配列と配列を組み合わせて使用することもできます。
$person[0]{'NAME'} = "Tanaka"; $person[0]{'AGE'} = 26; $person[1]{'NAME'} = "Suzuki"; $person[1]{'AGE'} = 32; for ($i = 0; $i <= $#person; $i++) { foreach $key ('NAME', 'AGE') { print "person[$i]{$key} = $person[$i]{$key}\n"; } }
結果は次のようになります。
person[0]{NAME} = Tanaka person[0]{AGE} = 26 person[1]{NAME} = Suzuki person[1]{AGE} = 32
連想配列と連想配列を多次元に組み合わせることもできます。この場合、each() はひとつめのキーと、そのキーに対応する連想配列への リファレンス を返します。
$person{'TANAKA'}{'AGE'} = 26; $person{'TANAKA'}{'ADDR'} = "東京"; $person{'SUZUKI'}{'AGE'} = 32; $person{'SUZUKI'}{'ADDR'} = "大阪"; while (($key, $ref) = each(%person)) { print "$key / $ref->{'AGE'} / $ref->{'ADDR'}\n"; }
結果は次のようになります。
SUZUKI / 32 / 大阪 TANAKA / 26 / 東京