Perl: 多次元連想配列
Perl で多次元のハッシュ(連想配列)を使うときのメモ。
多次元のハッシュは
my %foo;
$foo{$id1}{$id2} = $val;
で作れることはすぐに分かりましたが、全てのキーを列挙するやり方が分からなくて、大晦日の夜ずっと試行錯誤しながら悩んでいました。
while (my ($key1,$val1)=each(%foo)){
}
で1次元目のキーと、対応するハッシュのリファレンスを得ることが分かったのですが、ハッシュのリファレンスからどうやって2次元目のキーを生成すればいいのかが分かりませんでした。keys $$val1 とやってもエラーになります。リファレンスは、それ自身が参照先の型を知っているから $$val1 でハッシュにならないの?
年が明けて、Effective Perl を持っていたのを思い出して、リファレンスの項をみてようやく理解できました。まず、リファレンスの参照先をアクセス(デリファレンス)する方法は、
my $scalar="abc123";
my $ref_scalar=\$scalar;
print $$ref_scalar,"\n";
my @array=(aaa,bbb,ccc);
my $ref_array=\@array;
print @$ref_array,"\n";
my %hash=(a,AAA, b,BBB);
my $ref_hash=\%hash;
print %$ref_hash;
です。なるほどハッシュの場合は %$val でやればよいわけでした。
while (my ($key1,$val1)=(each %foo)){
while (my ($key2,$val2)=(each %$val1)){
print $key1,$key2,$val2;
}
}
正直なところ、このあたりは一度理解していたはずですが、使わない上に時間も空いてしまったので完全に忘れています。そういえば、Effective Perl に関しては2年近く前にこんな記事も書いていましたが、こちらもほとんど忘れています。
結局、ソートする必要があったので以下のようにしました。
foreach my $key1 (sort keys %foo)){
my $foo2 = $foo{$key1};
foreach my $key2 (sort {$foo2->{$a} <=> $foo2->{$b}} keys %$foo2){
print $key1,$key2,$foo2->{$val2};
}
}






