ハッシュのリファレンスで複雑なデータ構造を処理する

back
例えば

----
zaki,おにぎり,120
zaki,お茶,140
zaki,電車,120
zaki,服,19800
zaki,チャーハン,750
kouno,ラーメン,860
mokeke,餃子,820
kouno,ジュース,220
zaki,ビール,480
kouno,電車,520
zaki,電車,220
rina,バス,120
ketawo,お土産,1260
zaki,刺身,720
micky,サラダ,420
kouno,から揚げ,480
:
:
----

みたいな(相変わらず例が悪いよな…)、

誰(が全部でどれだけいるか不明)
何(が全部でどれだけあるか不明)
いくら

という、カンマ区切りの csv データファイルを

(誰)は(何)にお金を使ったのか
(誰)は合計(いくら)お金を使ったのか
(何)にお金を使ったのは(誰)か

といった感じに、いろいろ集計したい。

while (<CSV>) {
  ($name, $item, $price) = split(/,/);
  $value->{$name}->{$item}->{'count'} += 1;
  $value->{$name}->{$item}->{'price'} += $price;
}

以上で、全データを $value に格納する。

$value はハッシュのリファレンスで

{誰} -> {何} -> {'count'} に、(誰)が(何)に、何回お金を使ったか、の回数
{誰} -> {何} -> {'price'} に、(誰)が(何)に、合計いくら使ったか、の合計値

が格納される。

単発なら
「'zaki'が'電車'にお金を使った回数」は
$value->{'zaki'}->{'電車'}->{'count'}
「'zaki'が'電車'に使った金額の合計」は
$value->{'zaki'}->{'電車'}->{'price'}

(誰)を固定なら
「'zaki'は(何)にそれぞれいくら使ったか」は
foreach my $item (keys %{$value->{'zaki'}}){
  print "$item: $value->{'zaki'}->{$item}->{'price'}\n";
}

(何)を固定なら
「'ビール'には(誰)がそれぞれいくら使ったか」は
foreach my $name (keys %$value) {
  print "$name がビールに使った金額: $value->{$name}->{'ビール'}->{'price'}\n";
}
0 (というより undef)のデータも print されるので、$value->{$name}->{KEY}->{'count'} を
if でチェックして print すると良いかな。

とりあえず全部出力なら
foreach my $name (keys %$value) {
  foreach my $item (keys %{$value->{$name}}) {
    print "$name $item ";
    print $value->{$name}->{$item}->{'count'} . " ";
    print $value->{$name}->{$item}->{'price'} . "\n";
  }
}


みたいな感じ?

ほかにもやりかたあるかも。

back