【问题标题】:Better way to sum values in an array of hashes [closed]对哈希数组中的值求和的更好方法[关闭]
【发布时间】:2013-02-02 05:23:51
【问题描述】:

我需要对数组哈希中的值求和,我找到了一种方法来做到这一点here

但在 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")

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

【问题讨论】:

  • 这是正确的做法。你可以做的粗略方式: sum = 0;sales.each{|x| sum=sum+x["sale_price"]};sum
  • 感谢 Tin Man 的提示,我不知道代码审查网站。
  • “如果这样的事情能奏效就好了”。这是 Ruby,添加您想要的 Enumerable#sum 并解决问题。也许你应该称它为Enumerable#hash_sum,但Ruby 是一种OOP 语言,sum 应该是调用方法。

标签: ruby-on-rails ruby


【解决方案1】:

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

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

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

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

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

【讨论】:

  • 很好的答案。用作第二个 reduce 参数的 Symbol.to_proc (&:) 比仅编写普通块 .reduce(0){|t,i| t + i } 慢一个数量级,只有在您的数组可能包含大量元素时才值得注意。见igvita.com/2008/07/08/6-optimization-tips-for-ruby-mri#5。
  • 哇,很高兴知道。当您分析代码或深入挖掘时,您会发现惊人的结果。感谢您的信息。
  • 感谢您的解释。我仍在尝试了解 map/reduce,这可能就是为什么代码的意图对我来说不直观的原因。你有什么好的解释建议吗?
  • 我阅读代码的方式是:将销售对象列表映射到销售价格列表上,然后通过将价格组合成总价来减少它们。
  • 在 Rails 下,你可以去sales.map {|s| s['sale_price']}.sum。如果s 是一个带有sale_price 方法的对象,它可能会更简洁:sales.sum(&:sale_price) :D
【解决方案2】:

你可以让它工作:

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 可能是一个更好的名字)不是在数组上定义的,而是在特定的销售数组上定义的。

【讨论】:

    猜你喜欢
    • 2011-04-13
    • 2014-08-27
    • 1970-01-01
    • 2022-07-27
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 2015-01-06
    相关资源
    最近更新 更多