Perl: 多次元連想配列

2007年1月1日(月) 22時5分 by level
B ?

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};
  }
}
最終更新: 2009年9月2日(水) 21時52分

コメント (2)

1 9/02 19:36 おちんよ
(c1) [2009/09/02 19:36:00] by おちんよ

多次元連想配列の取り出し方ってすぐ忘れてしまいますよね^^;
参考になりました、ありがとうございます。

ですが、丸カッコが足りない気がしましたので、コメントさせて頂きました。

while (my ($key1,$val1)=(each %foo)){
while (my ($key2,$val2)=(each %$val1)){
print $key1,$key2,$val2;
}
}

2 9/02 21:56 level
(c2) [2009/09/02 21:56:10] by level

ありがとうございます。修正しておきました。
その上もおかしかったのでついでに見なおしました。

トラックバック

トラックバックは検索対象外です。