Ruby中多个哈希的摘要

时间:2016-10-31 15:42:33

标签: ruby-on-rails ruby hash sum

通过选择,我得到以下回复:

=> [{:month=>[3, 3, 9, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
:dates=>["30.10:", "29.10:", "28.10:", "27.10:", "26.10:", "25.10:", "24.10:", "23.10:", "22.10:", "21.10:", "20.10:", "19.10:", "18.10:", "17.10:", "16.10:", "15.10:", "14.10:", "13.10:", "12.10:", "11.10:", "10.10:", "09.10:", "08.10:", "07.10:", "06.10:", "05.10:", "04.10:", "03.10:", "02.10:", "01.10:"]},
{:month=>[1, 3, 5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
:dates=>["30.10:", "29.10:", "28.10:", "27.10:", "26.10:", "25.10:", "24.10:", "23.10:", "22.10:", "21.10:", "20.10:", "19.10:", "18.10:", "17.10:", "16.10:", "15.10:", "14.10:", "13.10:", "12.10:", "11.10:", "10.10:", "09.10:", "08.10:", "07.10:", "06.10:", "05.10:", "04.10:", "03.10:", "02.10:", "01.10:"]}]

在此示例中,有两组哈希值。可能会有更多结果 但每次的日期都是一样的。

有没有简单的方法将它与以下结果相结合?

[{:month=>[4, 6, 14, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
:dates=>["30.10:", "29.10:", "28.10:", "27.10:", "26.10:", "25.10:", "24.10:", "23.10:", "22.10:", "21.10:", "20.10:", "19.10:", "18.10:", "17.10:", "16.10:", "15.10:", "14.10:", "13.10:", "12.10:", "11.10:", "10.10:", "09.10:", "08.10:", "07.10:", "06.10:", "05.10:", "04.10:", "03.10:", "02.10:", "01.10:"]}

对于数组我可以使用transpose.map {|x| x.reduce(:+)}但不能用于哈希。 哈希是否有类似的解决方案?

2 个答案:

答案 0 :(得分:5)

arr = [{ :month=>[3, 3, 9], :dates=>["30.10:", "29.10:"] },
       { :month=>[1, 3, 5], :dates=>["30.10:", "29.10:"] },
       { :month=>[2, 4, 6], :dates=>["30.10:", "29.10:"] }]

{ :month=>arr.map { |h| h[:month] }.transpose.map { |a| a.reduce(:+) },
  :dates=>arr.first[:dates] }
  #=> {:month=>[6, 10, 20], :dates=>["30.10:", "29.10:"]} 

步骤如下。

a = arr.map { |h| h[:month] }
  #=> [[3, 3, 9], [1, 3, 5], [2, 4, 6]] 
b = a.transpose
  #=> [[3, 1, 2], [3, 3, 4], [9, 5, 6]] 
c = b.map { |a| a.reduce(:+) }
  #=> [6, 10, 20] 
d = arr.first
  #=> {:month=>[3, 3, 9], :dates=>["30.10:", "29.10:"]} 
e = d[:dates]
  #=> ["30.10:", "29.10:"] 
{ :month=>c, :dates=>e }
  #=> {:month=>[6, 10, 20], :dates=>["30.10:", "29.10:"]} 

答案 1 :(得分:2)

给出响应中的哈希数组:

@hashes = [{:month=>[3, 3, 9, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
:dates=>["30.10:", "29.10:", "28.10:", "27.10:", "26.10:", "25.10:", "24.10:", "23.10:", "22.10:", "21.10:", "20.10:", "19.10:", "18.10:", "17.10:", "16.10:", "15.10:", "14.10:", "13.10:", "12.10:", "11.10:", "10.10:", "09.10:", "08.10:", "07.10:", "06.10:", "05.10:", "04.10:", "03.10:", "02.10:", "01.10:"]},
{:month=>[1, 3, 5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
:dates=>["30.10:", "29.10:", "28.10:", "27.10:", "26.10:", "25.10:", "24.10:", "23.10:", "22.10:", "21.10:", "20.10:", "19.10:", "18.10:", "17.10:", "16.10:", "15.10:", "14.10:", "13.10:", "12.10:", "11.10:", "10.10:", "09.10:", "08.10:", "07.10:", "06.10:", "05.10:", "04.10:", "03.10:", "02.10:", "01.10:"]}]

您可以使用inject将它们组合在一起,并获得您在示例中提供的结果:

result = @hashes.inject({}) do |memo, hash|
  memo[:month] ||= []
  memo[:dates] ||= []
  memo[:month] += hash[:month]
  memo[:dates] += hash[:dates]
  memo
end

现在结果看起来像你的例子:

result == {
  :month=>[3, 3, 9, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
  :dates=>["30.10:", "29.10:", "28.10:", "27.10:", "26.10:", "25.10:", "24.10:", "23.10:", "22.10:", "21.10:", "20.10:", "19.10:", "18.10:", "17.10:", "16.10:", "15.10:", "14.10:", "13.10:", "12.10:", "11.10:", "10.10:", "09.10:", "08.10:", "07.10:", "06.10:", "05.10:", "04.10:", "03.10:", "02.10:", "01.10:", "30.10:", "29.10:", "28.10:", "27.10:", "26.10:", "25.10:", "24.10:", "23.10:", "22.10:", "21.10:", "20.10:", "19.10:", "18.10:", "17.10:", "16.10:", "15.10:", "14.10:", "13.10:", "12.10:", "11.10:", "10.10:", "09.10:", "08.10:", "07.10:", "06.10:", "05.10:", "04.10:", "03.10:", "02.10:", "01.10:"]
}