【问题标题】:Sum of hash keys in nested array in rubyruby 嵌套数组中哈希键的总和
【发布时间】:2015-05-10 01:35:03
【问题描述】:

我有一个数组,其中包含具有相同键集的哈希数组。我需要对每个数组的每组键求和,留下一个哈希数组。

array = [
  [{"x"=>"Apr, 2014", "price_rate"=>10, "cost_rate"=>10, "profit"=>10},
   {"x"=>"May, 2014", "price_rate"=>10, "cost_rate"=>10, "profit"=>10},
   {"x"=>"Jun, 2014", "price_rate"=>10, "cost_rate"=>10, "profit"=>10} ],
  [{"x"=>"Apr, 2014", "price_rate"=>10, "cost_rate"=>10, "profit"=>10},
   {"x"=>"May, 2014", "price_rate"=>10, "cost_rate"=>10, "profit"=>10},
   {"x"=>"Jun, 2014", "price_rate"=>10, "cost_rate"=>10, "profit"=>10} ],
  [{"x"=>"Apr, 2014", "price_rate"=>10, "cost_rate"=>10, "profit"=>10},
   {"x"=>"May, 2014", "price_rate"=>10, "cost_rate"=>10, "profit"=>10},
   {"x"=>"Jun, 2014", "price_rate"=>10, "cost_rate"=>10, "profit"=>10} ]
]

这会让我留下

[{"x"=>"Apr, 2014", "price_rate"=>30, "cost_rate"=>30, "profit"=>30},
 {"x"=>"May, 2014", "price_rate"=>30, "cost_rate"=>30, "profit"=>30},
 {"x"=>"Jun, 2014", "price_rate"=>30, "cost_rate"=>30, "profit"=>30} ]

我尝试将它们展平为一个数组,合并(这似乎永远不会给我预期的结果),然后减少到添加 - 但我无处可去。

有没有简洁的方法来做到这一点?

编辑 另外值得注意的是,每个数组中的哈希数可能会有所不同。该示例适用于一年的四分之一,但生成的解决方案应该足够不可知,以允许与数据集提供的一样多或尽可能少的条目。

【问题讨论】:

    标签: ruby-on-rails ruby arrays ruby-on-rails-4 hash


    【解决方案1】:

    这是一种(纯 Ruby)方式,它使用Hash#update(又名merge!)的形式,它使用一个块来确定被合并的两个哈希中存在的键的值:

    array.flatten.each_with_object({}) { |g,h|
      h.update(g["x"]=>g.dup) { |_,oh,nh|
        oh.update(nh) { |k,ov,nv| (k=="x") ? ov : ov+nv } } }.values
      #=> [{"x"=>"Apr, 2014", "price_rate"=>30, "cost_rate"=>30, "profit"=>30},
      #    {"x"=>"May, 2014", "price_rate"=>30, "cost_rate"=>30, "profit"=>30},
      #    {"x"=>"Jun, 2014", "price_rate"=>30, "cost_rate"=>30, "profit"=>30}]
    

    trh 指出我原来的解决方案修改了array,我错过了。为了避免这种情况,我将g["x"]=>g 更改为g["x"]=>g.dup

    【讨论】:

    • 这是完美的。我假设因为它正在更新;它实际上是在修改原始的“数组”对象......这对我来说很好。
    【解决方案2】:

    研究递归地使用 deep_merge。要使用 2 个哈希来执行此操作:

    hash1.deep_merge(hash2) { |key, first, last| key == 'x' ? first : first + last }
    

    这样做是合并每个键值,除了第一列(应该始终匹配)。如果您遍历所有数组,您应该能够使用类似的策略将它们合并为一个。

    更多信息:http://api.rubyonrails.org/classes/Hash.html#method-i-deep_merge

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-25
      • 2015-03-28
      • 2017-04-03
      • 2020-01-30
      • 1970-01-01
      • 2020-07-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多