计算 Ruby Hash 中嵌入数值的平均值

3
我有一个嵌入式哈希表,需要计算平均值。我已经成功地将它们从未分组的状态进行了分组,但是计算平均值对我来说并不起作用。
以下是示例哈希表数据。
myhash = {"2011-02-15"=>[["2011-02-15", 10], ["2011-02-15", 60]], 
          "2011-02-22"=>[["2011-02-22", 22]], 
          "2011-02-28"=>[["2011-02-28", 110],["2011-02-28", 70]]}

这是我如何将它们分组的(它们以前只是未分组的 {k => v})

@r = @myhash.group_by(&:first)

我尝试了这个线程中的两种解决方案(What's the best way in Ruby to average sets in an array?),但都没有成功。
好问题。我希望按日期平均结果,以便更好地提供服务。
[{"2012-02-15" => 35"}, {"2012-02-22" => 22"}, {"2012-02-28" => 90"}]

1
平均一堆字符串的定义是什么?你想要的结果是什么? - Linuxios
2个回答

7
Hash[myhash.map { |k,v| [k, v.map(&:last).inject(:+) / v.size] }]
#=> {"2011-02-15"=>35, "2011-02-22"=>22, "2011-02-28"=>90}

哇,你能解释一下在这种情况下注入是如何工作的吗?我以为它需要一个对象和一个块。 - Ismael
2
@ismaelga inject 可以接受一个方法符号来在每个值之间“注入”一个方法,使用当前元素调用该方法并将其应用于 memo。因此,inject(:+) 会被扩展为 inject { |memo, obj| memo.+(obj) }。当您不给 inject 提供初始值时,它只使用第一个元素。这里的文档值得一读 :) - Andrew Marshall
我读了,但是没理解。谢谢你的解释。但在这种情况下它与 reduce(:+) 有什么不同呢? - Ismael
@ismaelga 没有区别,reduce被别名为inject,因此使用其中一个而不是另一个仅仅是个人偏好。 - Andrew Marshall
哦,谢谢安德鲁,这很有道理。我猜只是为了语义上的补充。 - Ismael
@ismaelga 嗯,此外,“inject”(以及所有其他“-ect”方法,例如“select”,“reject”,“collect”)的名称来自Smalltalk,而别名则来自函数式语言。 - Andrew Marshall

0
在Rails中,Array类有一个sum方法。您可以按以下方式使用它:

方法1

{}.tap{ |h| myhash.each{ |date, list| h[date] = list.sum(&:last)/list.size}

方法二

Hash[myhash.map{ |date, list| [date, list.sum(&:last)/list.size] }]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接