Rails Ruby键的哈希值由键合并为平均值

时间:2014-03-12 10:42:50

标签: ruby-on-rails ruby arrays hash

我有一个activerecord方法,可以查找本周的所有事件,  myevents.map { |x| x.start_date.day => [x.title]} (start_date是一个datetime字段,title是一个字符串) 这给了我一系列哈希;

    [{11=>["40"]}, {11=>["0"]}, {11=>["0"]}, {11=>[""]}, 
     {11=>["0"]}, {11=>["0"]}, {11=>["33"]}, {12=>["9"]}, 
     {11=>["34"]}, {11=>["29"]}, {11=>["8"]}, {11=>["31"]}, 
     {11=>["40"]}, {11=>["34"]}] 

我想映射值,所以我得到一个看起来像的数组;

[ {11=>[ average of values that occur on the 11th]}, 
  {12=>[average of values that occur on the 12th]} ]

但我不太确定如何获得它。

2 个答案:

答案 0 :(得分:7)

我会使用group_byinjectmap

ar = [  
        {11=>["40"]}, {11=>["0"]}, {11=>["0"]}, {11=>[""]},
        {11=>["0"]}, {11=>["0"]}, {11=>["33"]}, {12=>["9"]},
        {11=>["34"]}, {11=>["29"]}, {11=>["8"]}, {11=>["31"]}, 
        {11=>["40"]}, {11=>["34"]}
     ]

# first grouping the inner hash keys like on 11,12,etc. In each iteration, 
# {11=>["40"]}, {11=>["0"]} are being passed to the block of `group_by`. Now
# `h.keys.first` gives 11 from `{11=>["40"]}` and 11 from `{11=>["0"]}` likewise.
ary = ar.group_by { |h| h.keys.first }.map do |k,v|
  { k => v.map { |h| h[k][0].to_i }.inject(:+) / v.size } 
end

ary # => [{11=>19}, {12=>9}]

答案 1 :(得分:0)

另一种方法: -

array = [  
        {11=>["40"]}, {11=>["0"]}, {11=>["0"]}, {11=>[""]},
        {11=>["0"]}, {11=>["0"]}, {11=>["33"]}, {12=>["9"]},
        {11=>["34"]}, {11=>["29"]}, {11=>["8"]}, {11=>["31"]}, 
        {11=>["40"]}, {11=>["34"]}
     ]

    array.each_with_object({}) { |hObj, newHash| hObj.each { |k,v| 
         (newHash[k] ||= []) << v.first.to_i } }.collect{|k,v| 
         {k => (v.inject(:+))/v.size}}

=> [{11=>19}, {12=>9}]