使用Ruby,如何将哈希数组合并按日期总计?

时间:2018-02-09 21:11:22

标签: arrays ruby

我有一个数组数组,每个数组包含给定周数的订单数。如何将这些合并在一起以得出每周的总和?

[
  [
    {:week_beginning=>Mon, 13 Feb 2017, :orders_total=>"1.00"}, 
    {:week_beginning=>Mon, 20 Feb 2017, :orders_total=>"3.00"}
  ], 
  [
    {:week_beginning=>Mon, 13 Feb 2017, :orders_total=>"2.00"}, 
    {:week_beginning=>Mon, 20 Feb 2017, :orders_total=>"7.00"}
  ], 
  [
    {:week_beginning=>Mon, 13 Feb 2017, :orders_total=>"3.00"},  
    {:week_beginning=>Mon, 20 Feb 2017, :orders_total=>"3.00"}
  ]
]

所以我最终得到了......?

[
  {:week_beginning=>Mon, 13 Feb 2017, :orders_total=>"6.00"}, 
  {:week_beginning=>Mon, 20 Feb 2017, :orders_total=>"13.00"}
]

1 个答案:

答案 0 :(得分:2)

arr成为您的数组,您可以使用Enumerable#group_by执行以下操作。

arr.flatten.group_by { |g| g[:week_beginning] }.
    map { |k,v| { week_beginning: k, orders_total: v.sum { |g|
      g[:orders_total].to_f }.to_s } }
 #=> [{:week_beginning=>"Mon, 13 Feb 2017", :orders_total=>"6.0"},
 #    {:week_beginning=>"Mon, 20 Feb 2017", :orders_total=>"13.0"}]

请注意

arr.flatten.group_by { |g| g[:week_beginning] }
  #=> {"Mon, 13 Feb 2017"=> [
  #      {:week_beginning=>"Mon, 13 Feb 2017", :orders_total=>"1.00"},
  #      {:week_beginning=>"Mon, 13 Feb 2017", :orders_total=>"2.00"},
  #      {:week_beginning=>"Mon, 13 Feb 2017", :orders_total=>"3.00"}
  #    ],
  #    "Mon, 20 Feb 2017"=>[
  #      {:week_beginning=>"Mon, 20 Feb 2017", :orders_total=>"3.00"},
  #      {:week_beginning=>"Mon, 20 Feb 2017", :orders_total=>"7.00"},
  #      {:week_beginning=>"Mon, 20 Feb 2017", :orders_total=>"3.00"}
  #    ]
  #   }

或者,您可以使用计算哈希(请参阅Hash::new的版本,其中new采用名为默认值的参数。

arr.flatten.each_with_object(Hash.new(0)) do |g,h|
  h.update(g[:week_beginning]=>g[:orders_total].to_f) { |_,o,n| o + n }
end.map { |k,v| {week_beginning: k, orders_total: v.to_s } }
  #=> [{:week_beginning=>"Mon, 13 Feb 2017", :orders_total=>"6.0"},
  #    {:week_beginning=>"Mon, 20 Feb 2017", :orders_total=>"13.0"}]

map的接收者如下。

arr.flatten.each_with_object(Hash.new(0)) do |g,h|
  h.update(g[:week_beginning]=>g[:orders_total].to_f) { |_,o,n| o + n }
end
  #=> {"Mon, 13 Feb 2017"=>6.0, "Mon, 20 Feb 2017"=>13.0}