18

我需要对数组哈希中的值求和,我在这里找到了一种方法

但它确实似乎在 Ruby 中应该有一种更优雅的方式。

这是有效的;

sales = [{"sale_price"=>210000, "deed_type"=>"Warranty Deed"}, {"sale_price"=>268300, "deed_type"=>"Warranty Deed Joint"}]

total_sales = sales.inject(0) {|sum, hash| sum + hash["sale_price"]}

总计行不是很可读。如果这样的事情有效,那就太好了;

total_sales = sales.sum("sale_price")

这只是一厢情愿还是我忽略了更好的解决方案?

4

2 回答 2

39

我喜欢像这样使用 map/reduce 隐喻:

total_sales = sales.map {|s| s['sale_price']}.reduce(0, :+)

reduce 方法是 inject 方法的同义词,我发现 inject 这个名字与 memo 组件有些混淆。它具有我上面使用的另一种形式来获取初始值和对用于组合/归约过程的方法调用的引用。

我认为映射值然后将它们减少为聚合的整体模式是众所周知的并且是自记录的。

编辑:使用符号 :+ 而不是 proc 引用 &:+

于 2013-02-01T20:54:15.320 回答
4

你可以让它工作:

sales = [{"sale_price"=>210000, "deed_type"=>"Warranty Deed"}, {"sale_price"=>268300, "deed_type"=>"Warranty Deed Joint"}]

def sales.sum(by)
  inject(0){|sum, h| sum + h[by]}
end

p sales.sum("sale_price") #=> 478300

请注意,此sum方法(sum_by 可能是一个更好的名称)未在 Array 上定义,而仅在特定的 sales 数组上定义。

于 2013-02-01T21:15:55.140 回答