I have an array of arrays, each containing the number of orders by a given week. How do I merge this together to give a sum total for each week?
[
[
{: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"}
]
]
So that I end up with..?
[
{:week_beginning=>Mon, 13 Feb 2017, :orders_total=>"6.00"},
{:week_beginning=>Mon, 20 Feb 2017, :orders_total=>"13.00"}
]
Letting arr
be your array, you can do the following using 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"}]
Note that
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"}
# ]
# }
Alternatively, you could use a counting hash (see the version of Hash::new where new
takes an argument called the default value ).
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
's receiver is the following.
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}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.