使用相同的键在数组中合并/添加哈希值

问题描述 投票:-1回答:5

我有一系列哈希:

array = [
  {"points": 0, "block": 3},
  {"points": 25, "block": 8},
  {"points": 65, "block": 4}
]

我需要合并哈希。我需要输出为:

{"points": 90, "block": 15}
ruby hash
5个回答
1
投票

如果你有这个结构中提到的数组:

array = [
  {"points": 0, "block": 3},
  {"points": 25, "block": 8},
  {"points": 65, "block": 4}
]

您可以使用以下代码来实现目标:

result = {
  points: array.map{ |item| item[:points] }.inject(:+),
  block: array.map{ |item| item[:block] }.inject(:+)
}

你会得到这个结果:

{:points=>90, :block=>15}

注意:这将在数组上迭代两次。我试图想出一个更好的方法来迭代一次,仍然有相同的优雅/易于准备的代码。

如果你想更普遍地做(比:points:block更多的键),那么你可以使用这个代码:

array = [
  {"points": 0, "block": 3},
  {"points": 25, "block": 8},
  {"points": 65, "block": 4}
]

keys = [:points, :block] # or you can make it generic with array.first.keys

result = keys.map do |key|
  [key, array.map{ |item| item.fetch(key, 0) }.inject(:+)]
end.to_h

4
投票

你可以一起merge哈希值,添加两个哈希值中的值:

result = array.reduce do |memo, next_hash|
  memo.merge(next_hash) do |key, memo_value, next_hash_value|
    memo_value + next_hash_value
  end
end
result # => {:points=>90, :block=>15}

如果您的真实散列具有对+不能很好响应的键,则可以访问key,您可以设置case语句,以便在需要时以不同方式处理键。


1
投票

您可以创建如下方法来获得结果

def process_array(array)
   points = array.map{|h| h[:points]}
   block = array.map{|h| h[:block]}
   result = {}
   result['points'] = points.inject{ |sum, x| sum + x }
   result['block'] = block.inject{ |sum, x| sum + x }
  result
end

并使用数组输入调用该方法将为您提供预期的结果。

[54] pry(main)> process_array(array)
=> {"points"=>90, "block"=>15}

0
投票

您还可以使用枚举器each_with_object,使用哈希作为对象。

result = array.each_with_object(Hash.new(0)) {|e, h| h[:points] += e[:points]; h[:block] += e[:block] }
# => {:points=>90, :block=>15}

Hash.new(0)对于任何键都意味着initialise the hash to default value 0,例如:

h = Hash.new(0)
h[:whathever_key] # => 0

0
投票

我感兴趣的是“Simple Lime”引入的reduce方法是如何工作的,以及它如何针对数组上的简单迭代和每个哈希的键进行基准测试。

以下是“迭代”方法的代码:

Hash.new(0).tap do |result|
  array.each do |hash|
    hash.each do |key, val|
      result[key] = result[key] + val
    end
  end
end

我很惊讶,“迭代”代码比reduce方法执行了3倍。

这是基准代码https://gist.github.com/landovsky/6a1b29cbf13d0cf81bad12b6ba472416

© www.soinside.com 2019 - 2024. All rights reserved.