Ruby-on-rails 对哈希数组中的值求和的更好方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14654720/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 21:21:49  来源:igfitidea点击:

Better way to sum values in an array of hashes

ruby-on-railsruby

提问by SteveO7

I need to sum values in an array hashes and I found a way to do it here

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

but it sure seems like there should be a more elegant way in Ruby.

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

Here is what works;

这是有效的;

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"]}

The totals line is not very readable. It would be nice if something like this worked;

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

total_sales = sales.sum("sale_price")

Is this just wishful thinking or am I overlooking a better solution?

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

回答by Winfield

I like using the map/reduce metaphor like so:

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

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

The reduce method is a synonym for the inject method, I find the name inject to be somewhat confusing with the memo component. It has another form I use above to take the initial value and a reference to a method call used for the combination/reduction process.

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

I think the overall pattern of mapping the values and then reducing them to an aggregate is well known and self-documenting.

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

EDIT: Use symbol :+ instead of proc reference &:+

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

回答by steenslag

You can make it work:

你可以让它工作:

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

Note this summethod (sum_by might be a better name) is not defined on Array, but only on the specific sales array.

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