如何在ruby中合并哈希数组中的值?

时间:2014-03-04 06:43:45

标签: ruby arrays hash

我有这样的哈希数组:

a = [{:transaction_type=>"nationalvoice", :transaction_duration=>181}, {:transaction_type=>"nationalvoice", :transaction_duration=>60}, {:transaction_type=>"call", :transaction_duration=>200}]

如何合并基于值的transaction_type =“nationalvoice”?

我希望得到这样的结果:

a = [{:transaction_type=>"nationalvoice", :transaction_duration=>241}, {:transaction_type=>"call", :transaction_duration=>200}]

怎么做?

之前感谢

3 个答案:

答案 0 :(得分:2)

执行以下操作:

a = [{:transaction_type=>"nationalvoice", :transaction_duration=>181}, {:transaction_type=>"nationalvoice", :transaction_duration=>60}, {:transaction_type=>"call", :transaction_duration=>200}]


array_merge_hash = a.group_by { |hash1| hash1[:transaction_type] }.map do |_,v|
  v.inject do |ele_hash2,ele_hash1| 
     ele_hash2.merge(ele_hash1) {|k,o,n| k == :transaction_duration ? o+n : o }
  end
end

答案 1 :(得分:0)

使用Enumerable#group_by

a = [
  {:transaction_type=>"nationalvoice", :transaction_duration=>181},
  {:transaction_type=>"nationalvoice", :transaction_duration=>60},
  {:transaction_type=>"call", :transaction_duration=>200},
]

groups = a.group_by { |h| h[:transaction_type] }
# => {"nationalvoice"=>[
#      {:transaction_type=>"nationalvoice", :transaction_duration=>181},
#      {:transaction_type=>"nationalvoice", :transaction_duration=>60}
#    ],
#    "call"=>[
#      {:transaction_type=>"call", :transaction_duration=>200}
#    ]}

merged_hashes = groups.map { |k, hashes|
  total = hashes.map { |h| h[:transaction_duration] }.reduce(:+)
  {transaction_type: k, transaction_duration: total} # merged hash
}

# => [{:transaction_type=>"nationalvoice", :transaction_duration=>241},
#     {:transaction_type=>"call", :transaction_duration=>200}]

答案 2 :(得分:0)

您也可以使用Enumerable#each_with_object

a =[{:transaction_type=>"nationalvoice", :transaction_duration=>181}, {:transaction_type=>"nationalvoice", :transaction_duration=>60}, {:transaction_type=>"call", :transaction_duration=>200}]
n = a.each_with_object({}) do |obj,hsh|
   hsh[obj[:transaction_type]] ? hsh[obj[:transaction_type]][:transaction_duration]+= obj[:transaction_duration].to_i : hsh[obj[:transaction_type]]=obj
end
print n.values

# [{:transaction_type=>"nationalvoice", :transaction_duration=>241}, {:transaction_type=>"call", :transaction_duration=>200}]