2

私はRubyが初めてで、問題を解決しようとしています。私はハッシュの配列を持っています:

list = [{"amount"=>2.25,"rel_id"=>1103, "date"=>"2012-12-21"},
 {"amount"=>2.75,"rel_id"=>1103, "date"=>"2012-12-24"},
 {"amount"=>2.85,"rel_id"=>666, "date"=>"2012-12-27"},
 {"amount"=>3.15,"rel_id"=>666, "date"=>"2012-12-28"}
 #and many many more..
]

これらを rel_id でグループ化する必要があります。これにより、合計金額と日付を次のような形式で確認できます。

{1103=>{:total_amount=>5.0, :dates=>["2012-12-21", "2012-12-24"]}, 666=>{:total_amount=>6.0, :dates=>["2012-12-27", "2012-12-28"]}}

私はこれをこの方法で解決しましたが、それはそれを行うための最悪のアプローチの1つであると確信しており、ルビーの方法ではないと思います..

results = {}

list.each do |line|
 if !(results.has_key?(line["rel_id"]))
 results[line["rel_id"]]={:total_amount=>line["amount"],:dates=>[line["date"]]}
 else
 results[line["rel_id"]][:total_amount] = results[line["rel_id"]][:total_amount]+line["amount"]
 results[line["rel_id"]][:dates]<<line["date"]
 end
end

たぶん、ルビーの方法でより美しく、より美しいアプローチを実装する方法を教えてください。

4

4 に答える 4

5

次のようなことができます。

list.each_with_object({}) do |details, rollup|
  rollup[details["rel_id"]] ||= { total_amount: 0, dates: [] }
  rollup[details["rel_id"]][:total_amount] += details["amount"]
  rollup[details["rel_id"]][:dates] << details["date"]
end

読みやすさ/名前のために編集されました。

于 2013-08-14T18:34:51.583 に答える
1

機能的アプローチ (使用します。ファセットがない場合は使用します) mash:Hash[...]

purchases_grouped = list.group_by { |p| p["rel_id"] }
result = purchases_grouped.mash do |rel_id, purchases|
  total_amount = purchases.map { |p| p["amount"] }.reduce(:+)
  dates = purchases.map { |p| p["date"] }
  accumulated = {total_amount: total_amount, dates: dates}
  [rel_id, accumulated]
end
#=> {1103=>{:total_amount=>5.0, :dates=>["2012-12-21", "2012-12-24"]}, 
#    666 =>{:total_amount=>6.0, :dates=>["2012-12-27", "2012-12-28"]}}
于 2013-08-14T18:54:27.293 に答える
0
list = [
 {amount: 2.25, rel_id: 1103, date: "2012-12-21"},
 {amount: 2.75, rel_id: 1103, date: "2012-12-24"},
 {amount: 2.85, rel_id: 666, date: "2012-12-27"},
 {amount: 3.15, rel_id: 666, date: "2012-12-28"},
]

results = Hash.new do |hash, key| 
  hash[key] = {}
end

list.each do |hash|
  totals = results[hash[:rel_id]]

  totals[:amount] ||= 0
  totals[:amount] += hash[:amount]

  totals[:dates] ||= []
  totals[:dates] << hash[:date]
end

p results

--output:--
{1103=>{:amount=>5.0, :dates=>["2012-12-21", "2012-12-24"]}, 
 666=>{:amount=>6.0, :dates=>["2012-12-27", "2012-12-28"]}}

Alex Peachey の each_with_object ソリューションが変更されました。

results =  list.each_with_object({}) do |h, acc|
  record = acc[h["rel_id"]] 
  record ||= { total_amount: 0, dates: [] }
  record[:total_amount] += h["amount"]
  record[:dates] << h["date"]
end
于 2013-08-14T18:48:52.510 に答える