Ruby on rails 嵌套哈希中相同键的键值对之和
我有以下哈希数组-Ruby on rails 嵌套哈希中相同键的键值对之和,ruby-on-rails,ruby,arrays,hash,Ruby On Rails,Ruby,Arrays,Hash,我有以下哈希数组- array = [{:Air_Duct_Cleaning=>{:impressions=>92, :clicks=>2, :conversions=>0}, :Carpet_Cleaning=>{:impressions=>297, :clicks=>0, :conversions=>0}, :Brand_Terms=>{:impressions=>273, :clicks=>9, :conversions=&
array = [{:Air_Duct_Cleaning=>{:impressions=>92, :clicks=>2, :conversions=>0}, :Carpet_Cleaning=>{:impressions=>297, :clicks=>0, :conversions=>0}, :Brand_Terms=>{:impressions=>273, :clicks=>9, :conversions=>1}}, {:Brand_Terms=>{:impressions=>275, :clicks=>3, :conversions=>0}}, {:Air_Duct_Cleaning=>{:impressions=>51, :clicks=>1, :conversions=>0}, :Carpet_Cleaning=>{:impressions=>225, :clicks=>0, :conversions=>0}, :Brand_Terms=>{:impressions=>326, :clicks=>12, :conversions=>2}}]
我正在尝试对相同键的键值对求和。例如—
air_duct = array.map {|m| m[:Air_Duct_Cleaning]}.compact
=> [{:impressions=>92, :clicks=>2, :conversions=>0}, {:impressions=>51, :clicks=>1, :conversions=>0}]
air_duct_total = air_duct.inject{|x,y| x.merge(y){|a,b,c| b + c}}
=> {:impressions=>143, :clicks=>3, :conversions=>0}
但是,我需要在不知道第一级哈希的键的情况下执行此操作(不知道:Air\u Duct\u Cleaning
)的键)。我试着遍历数组,运行类似
key_groups = array.map {|m| m.map {|key, value| key}}
[{:Air_Duct_Cleaning =>{:impressions=>92, :clicks=>2, :conversions=>0}, {:impressions=>51, :clicks=>1, :conversions=>0}, {:Carpet_Cleaning => {:impressions=>297, :clicks=>0, :conversions=>0}, {:impressions=>225, :clicks=>0, :conversions=>0}, {:Brand_Terms => {:impressions=>273, :clicks=>9, :conversions=>1}, {:impressions=>275, :clicks=>3, :conversions=>0}, {:impressions=>326, :clicks=>12, :conversions=>2}]
totals = key_groups.map {|m| m.inject{|x,y| x.merge(y){|a,b,c| b + c}}}
希望这会将每个键放置在:风道清洁的位置,我会得到类似
key_groups = array.map {|m| m.map {|key, value| key}}
[{:Air_Duct_Cleaning =>{:impressions=>92, :clicks=>2, :conversions=>0}, {:impressions=>51, :clicks=>1, :conversions=>0}, {:Carpet_Cleaning => {:impressions=>297, :clicks=>0, :conversions=>0}, {:impressions=>225, :clicks=>0, :conversions=>0}, {:Brand_Terms => {:impressions=>273, :clicks=>9, :conversions=>1}, {:impressions=>275, :clicks=>3, :conversions=>0}, {:impressions=>326, :clicks=>12, :conversions=>2}]
totals = key_groups.map {|m| m.inject{|x,y| x.merge(y){|a,b,c| b + c}}}
这样我就可以使用
key_groups = array.map {|m| m.map {|key, value| key}}
[{:Air_Duct_Cleaning =>{:impressions=>92, :clicks=>2, :conversions=>0}, {:impressions=>51, :clicks=>1, :conversions=>0}, {:Carpet_Cleaning => {:impressions=>297, :clicks=>0, :conversions=>0}, {:impressions=>225, :clicks=>0, :conversions=>0}, {:Brand_Terms => {:impressions=>273, :clicks=>9, :conversions=>1}, {:impressions=>275, :clicks=>3, :conversions=>0}, {:impressions=>326, :clicks=>12, :conversions=>2}]
totals = key_groups.map {|m| m.inject{|x,y| x.merge(y){|a,b,c| b + c}}}
最终以
[{:Air_Duct_Cleaning => {:impressions=>143, :clicks=>3, :conversions=>0}, {:Carpet_Cleaning => {:impressions=>522, :clicks=>0, :conversions=>0}, {:Brand_Terms => {:impressions=>874, :clicks=>24, :conversions=>3}]
这将产生所需的输出,而无需使用输入数组的显式键:
array = [
{ Air_Duct_Cleaning: { impressions: 92, clicks: 2, conversions: 0 }, Carpet_Cleaning: { impressions: 297, clicks: 0, conversions: 0 }, Brand_Terms: { impressions: 273, clicks: 9, conversions: 1 }},
{ Brand_Terms: { impressions: 275, clicks: 3, conversions: 0 }},
{ Air_Duct_Cleaning: { impressions: 51, clicks: 1, conversions: 0 }, Carpet_Cleaning: { impressions: 225, clicks: 0, conversions: 0 }, Brand_Terms: { impressions: 326, clicks: 12, conversions: 2 }},
]
result = array.reduce({}) do |o, hash|
o.merge(hash) { |_, v1, v2| v1.merge(v2) { |_, vv1, vv2| vv1 + vv2 } }
end
p result
# {
# :Air_Duct_Cleaning=>{:impressions=>143, :clicks=>3, :conversions=>0},
# :Carpet_Cleaning=>{:impressions=>522, :clicks=>0, :conversions=>0},
# :Brand_Terms=>{:impressions=>874, :clicks=>24, :conversions=>3}
# }