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

时间:2018-09-01 12:14:01

标签: ruby hash

我有一个哈希数组:

    navigationController?.navigationBar.backIndicatorImage = #imageLiteral(resourceName: "backArrow").withRenderingMode(.automatic)
    navigationController?.navigationBar.backIndicatorTransitionMaskImage = UIImage(named: "backArrow")
    navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
    navigationItem.backBarButtonItem?.tintColor = UIColor(red: 235/255, green: 235/255, blue: 235/255, alpha: 1)

我需要合并哈希。我需要的输出是:

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

5 个答案:

答案 0 :(得分: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 :(得分: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

答案 2 :(得分: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}

答案 3 :(得分:0)

您还可以将枚举作为对象使用枚举器http://api.jquery.com/off/

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)表示each_with_object 0对于任何键,例如:

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

答案 4 :(得分: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