我建議@奧列格的做法,但總有另一種方式:
個
arr = [[["12:00", 7.0], ["01:00", 3.3], ["02:00", 11.9], ["03:00", 56.5]],
[["12:00", 44.3], ["01:00", 2.25], ["02:00", 2.44], ["03:00", 46.11],
["04:00", 8.9]],
[["01:00", 22.25], ["02:00", 1.84], ["12:00", 13.3]]]
keys = arr.reduce([]) { |keys,a| keys | a.map(&:first) }
arr.map { |a| a.to_h.values_at(*keys) }
.transpose
.map { |e| [keys.shift, e.reduce(0) { |tot,x| tot + x.to_f }] }
#=> [["12:00", 64.6], ["01:00", 27.8], ["02:00", 16.18],
# ["03:00", 102.61], ["04:00", 8.9]]
步驟:
keys = arr.reduce([]) { |keys,a| keys | a.map(&:first) }
#=> ["12:00", "01:00", "02:00", "03:00", "04:00"]
b = arr.map { |a| a.to_h.values_at(*keys) }
#=> [[ 7.0, 3.3, 11.9, 56.5, nil],
# [44.3, 2.25, 2.44, 46.11, 8.9],
# [13.3, 22.25, 1.84, nil, nil]]
c = b.transpose
#=> [[7.0, 44.3, 13.3],
# [3.3, 2.25, 22.25],
# [11.9, 2.44, 1.84],
# [56.5, 46.11, nil],
# [nil, 8.9, nil]]
c.map { |e| [keys.shift, e.reduce(0) { |tot,x| tot + x.to_f }] }
#=> [["12:00", 64.6], ["01:00", 27.8], ["02:00", 16.18],
# ["03:00", 102.61], ["04:00", 8.9]]
注意NilClass#to_f轉換nil
到0.0
。
要精心b
上面的計算:
d = arr.map
#=> #<Enumerator: [[["12:00", 7.0], ["01:00", 3.3], ["02:00", 11.9],
# ["03:00", 56.5]],
# [["12:00", 44.3], ["01:00", 2.25], ["02:00", 2.44],
# ["03:00", 46.11], ["04:00", 8.9]],
# [["01:00", 22.25], ["02:00", 1.84], ["12:00", 13.3]]]:map>
a = d.next
#=> [["12:00", 7.0], ["01:00", 3.3], ["02:00", 11.9], ["03:00", 56.5]]
e = a.to_h
#=> {"12:00"=>7.0, "01:00"=>3.3, "02:00"=>11.9, "03:00"=>56.5}
f = e.values_at(*keys)
#=> e.values_at(*["12:00", "01:00", "02:00", "03:00", "04:00"])
#=> [7.0, 3.3, 11.9, 56.5, nil]
a = d.next
#=> [["12:00", 44.3], ["01:00", 2.25], ["02:00", 2.44],
# ["03:00", 46.11], ["04:00", 8.9]]
e = a.to_h
#=> {"12:00"=> 44.3, "01:00"=>2.25, "02:00"=>2.44,
# "03:00"=>46.11, "04:00"=> 8.9}
f = e.values_at(*keys)
#=> [44.3, 2.25, 2.44, 46.11, 8.9]
a = d.next
#=> [["01:00", 22.25], ["02:00", 1.84], ["12:00", 13.3]]
e = a.to_h
#=> {"01:00"=>22.25, "02:00"=>1.84, "12:00"=>13.3}
f = e.values_at(*keys)
#=> [13.3, 22.25, 1.84, nil, nil]
c.map
計算如下:
keys = ["12:00", "01:00", "02:00", "03:00", "04:00"]
d = c.map
#=> #<Enumerator: [[ 7.0, 44.3, 13.3], [3.3, 2.25, 22.25],
# [11.9, 2.44, 1.84], [56.5, 46.11, nil],
# [nil, 8.9, nil]]:map>
e = d.next
#=> [7.0, 44.3, 13.3]
f = keys.shift
#=> "12:00"
keys
#=> ["01:00", "02:00", "03:00", "04:00"]
e.reduce(0) { |tot,x| tot + x.to_f }
#=> 64.6
e = d.next
#=> [3.3, 2.25, 22.25]
f = keys.shift
#=> "01:00"
keys
#=> ["02:00", "03:00", "04:00"]
e.reduce(0) { |tot,x| tot + x.to_f }
#=> 27.8
e = d.next
#=> [11.9, 2.44, 1.84]
f = keys.shift
#=> "02:00"
keys
#=> ["03:00", "04:00"]
e.reduce(0) { |tot,x| tot + x.to_f }
#=> 16.18
e = d.next
#=> [56.5, 46.11, nil]
f = keys.shift
#=> "03:00"
keys
#=> ["04:00"]
e.reduce(0) { |tot,x| tot + x.to_f }
#=> 102.61
e = d.next
#=> [nil, 8.9, nil]
f = keys.shift
#=> "04:00"
keys
#=> []
e.reduce(0) { |tot,x| tot + x.to_f }
#=> 8.9
很好的回答,但我建議(因爲OP使用術語「幾個」),你將它概括爲'sum_arrays(arr)',其中'arr = [a,b,...]'。你可能不得不將'merge'改成'merge!'(又名'update')。此外,提供指向方法[Hash#merge](http://ruby-doc.org/core-2.2.0/Hash.html#method-i-merge)的鏈接並解釋您使用表單該方法使用塊來確定正在合併的兩個哈希中存在的鍵的值。 – 2015-03-30 23:51:17
謝謝。多於兩個數組的更多行更新了答案。 – 2015-03-31 00:29:37
很酷的使用哈希#合併和#to_a。 – Puhlze 2015-03-31 02:24:55