惯用Ruby:数据结构转换

Kev*_*eil 1 ruby hash merge transformation data-structures

什么是"Rubyist"方式进行以下数据结构转换:

我有

    incoming = [ {:date => 20090501, :width => 2}, 
                 {:date => 20090501, :height => 7}, 
                 {:date => 20090501, :depth => 3}, 
                 {:date => 20090502, :width => 4}, 
                 {:date => 20090502, :height => 6}, 
                 {:date => 20090502, :depth => 2},
               ]

我希望通过以下方式折叠这些:日期,最终结束

    outgoing = [ {:date => 20090501, :width => 2, :height => 7, :depth => 3},
                 {:date => 20090502, :width => 4, :height => 6, :depth => 2},
               ]

如果列在每行中的顺序相同,则最后一步也可以使用数组数组.另外,重要的是,我事先并不知道所有的哈希键(也就是说,我不知道:宽度,高度,或:深度 - 它们可能是:猫,狗,和:仓鼠).

Tor*_*rud 8

如果使用Ruby 1.8.7或Ruby 1.9+,下面的代码读得很好:

incoming.group_by{|hash| hash[:date]}.map do |_, hashes| 
  hashes.reduce(:merge)
end
Run Code Online (Sandbox Code Playgroud)

块属性(_,哈希)中的下划线表示我们不需要/关心该特定属性.

#reduce是#inject的别名,用于将集合缩减为单个项目.在新的Ruby版本中,它还接受一个符号,这是用于进行缩减的方法的名称.

它首先通过调用集合中第一个项目的方法,第二个项目作为参数.然后,它会在结果上再次调用该方法,并将第三个项目作为参数,依此类推,直到没有更多项目为止.

[1, 3, 2, 2].reduce(:+) => [4, 2, 2] => [6, 2] => 8
Run Code Online (Sandbox Code Playgroud)