• ベストアンサー

配列をグループ化して出力したい。

例えば @raiten=( 1,12/1,山田花子,200, 2,12/3,日本タロウ,300, 3,12/4,山田花子,50, 4,12/6,日本タロウ,100, 5,12/7,鈴木一郎,60, 6,12/10,山田花子,200, ) のような配列があったとします。ちなみに上の配列は(順番,日付,名前,購入金額,)の並びです。 これをもとに名前でSQLでいうグループ化をしたいのです。 最終的には下のように出力したいのです。 山田花子の購入金額は合計で450円 日本タロウの購入金額は合計で400円 鈴木一郎の購入金額は合計で200円 いい方法がみつかりません。どなたかご教授いただけますでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.5

>簡単なハッシュならわかるのですが、ここまでくるとなかなか難しいです。 名前によるハッシュ値=[合計、購入品のハッシュ]の配列 になっているだけです。配列の部分は無名配列になっています。 ちなみに、#3の方の場合は、 名前によるハッシュ値={合計、購入品の配列}のハッシュ になっています。 >ハッシュを使っての色々なテクニックを書いてある書籍はないですか? オライリーのクックブックがお勧めです。

bakusui
質問者

お礼

本当にご丁寧にありがとうございました。 更なる勉強をしていきます。

その他の回答 (4)

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.4

#回答がすでにでているので止めようかと思ったんですが、 #やってることは、#3の方とほとんど同じですが #購入品の履歴でなく種類にしてみました。 @raiten=( '1,12/1,山田花子,200,りんご', '2,12/3,日本タロウ,300,バナナ', '3,12/4,山田花子,50,みかん', '4,12/6,日本タロウ,100,パイン', '5,12/7,鈴木一郎,60,メロン', '6,12/10,山田花子,200,すいか', '7,12/11,山田花子,50,みかん', ); my %kyaku; foreach (@raiten){ my ($no, $date, $name, $money, $kind) = split /,/; unless($kyaku{$name}){ $kyaku{$name} =[0, {}]; } $kyaku{$name}[0] += $money; $kyaku{$name}[1]{$kind}++; } # 集計結果を出力する。 foreach my $name (keys %kyaku){ print "$nameの購入した金額は合計で$kyaku{$name}[0]で", join( ',', keys %{$kyaku{$name}[1]}),"を購入しています。<br>\n"; }

bakusui
質問者

お礼

重ね重ねありがとうございます。 そのままつかってみてうまくうごいているので感動しています。 でもいったいどうなっているのか構造が複雑ですね・・・ 簡単なハッシュならわかるのですが、ここまでくるとなかなか難しいです。 ハッシュをつかってのいろいろなテクニックを書いてあるサイトか書籍はないですか? BLUEPIXYさんはどこで勉強を??

  • okiyoshi
  • ベストアンサー率34% (11/32)
回答No.3

# > ではたとえば、 # でわ、以下でどうでしょう。 # ・・次はどの商品が一番売れているか?の集計も必要だったりして・・ # ・・なんだか宿題を代行しているような・・ # 配列(裸の文字列)はエラーとなるので、 # 商品名までクオートで囲まれているとして、 use strict; my @raiten = ( '1,12/1,山田花子,200,りんご', '2,12/3,日本タロウ,300,バナナ', '3,12/4,山田花子,50,みかん', '4,12/6,日本タロウ,100,パイン', '5,12/7,鈴木一郎,60,メロン', '6,12/10,山田花子,200,すいか', ); # 氏名をキーとしてハッシュの構造体に集計する。 my %kyaku; for( @raiten ){ my @dat = split /,/; $kyaku{$dat[2]}{'金額'} += $dat[3]; push @{$kyaku{$dat[2]}{'商品'}}, $dat[4]; } # 集計結果を出力する。 for( sort keys %kyaku ){ my $syohin = join ',', @{$kyaku{$_}{'商品'}}; print "$_の購入した金額は合計で$kyaku{$_}{'金額'}で", "${syohin}を購入しています。<br>\n"; }

bakusui
質問者

お礼

すばらいい。感動しました。 いやーー勉強させていただきました。 本当にありがとうございます。 いままでほとんどハッシュを使わず強引に配列でやってたのがばかばかしいです。 ハッシュをもっと深くまで勉強します。 重ね重ねありがとうございました。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.2

#やってることは、#1の方と同じですが、 #データがまとまりになってない場合 @raiten=( 1,'12/1','山田花子',200, 2,'12/3','日本タロウ',300, 3,'12/4','山田花子',50, 4,'12/6','日本タロウ',100, 5,'12/7','鈴木一郎',60, 6,'12/10','山田花子',200, ); @datas = @raiten; #コピーで作業する %sum=undef; while(@datas){ ($no,$date,$name,$money)=splice(@datas, 0, 4); $sum{$name}+=$money; } while(($name, $value)=each(%sum)){ print "$nameの購入金額は合計で$value円\n"; }

bakusui
質問者

お礼

さらにわかりやすい解説感謝します。 1の方にも書きましたが、以下のような方法はありますか? @raiten = ( '1,12/1,山田花子,200',りんご, '2,12/3,日本タロウ,300',バナナ, '3,12/4,山田花子,50',みかん, '4,12/6,日本タロウ,100',パイン, '5,12/7,鈴木一郎,60',メロン, '6,12/10,山田花子,200',すいか, ); のように購入したものを配列に追加して print "○○の購入した金額は合計でxx円でりんご,みかん,すいかを購入しています。<br>\n"; のように文字と数値の合計を同時に集計した結果を出力は可能でしょうか?

  • okiyoshi
  • ベストアンサー率34% (11/32)
回答No.1

# > のような配列があったとします。 # という配列(裸の文字列)はエラーとなるので、 # 以下のようにクオートで囲まれている場合と同様なデータとして、 my @raiten = ( '1,12/1,山田花子,200', '2,12/3,日本タロウ,300', '3,12/4,山田花子,50', '4,12/6,日本タロウ,100', '5,12/7,鈴木一郎,60', '6,12/10,山田花子,200', ); # 氏名をキーとしてハッシュに集計する my %kyaku; for( @raiten ){ my @dat = split /,/; $kyaku{$dat[2]} += $dat[3]; } # 集計結果を出力 print "$_の購入金額は合計で$kyaku{$_}円\n" for( sort keys %kyaku );

bakusui
質問者

お礼

わかりやすい解説ありがとうございます。 合計をだしたいならハッシュをつかうんですね。 ではたとえば、 @raiten = ( '1,12/1,山田花子,200',りんご, '2,12/3,日本タロウ,300',バナナ, '3,12/4,山田花子,50',みかん, '4,12/6,日本タロウ,100',パイン, '5,12/7,鈴木一郎,60',メロン, '6,12/10,山田花子,200',すいか, ); のように購入したものを配列に追加して print "○○の購入した金額は合計でxx円でりんご,みかん,すいかを購入しています。<br>\n"; のように文字と数値の合計を同時に集計した結果を出力は可能でしょうか?

関連するQ&A