简体   繁体   English

如何根据ruby中的相同键合并哈希数组?

[英]How to merge array of hash based on the same keys in ruby?

How to merge array of hash based on the same keys in ruby?如何根据ruby中的相同键合并哈希数组?

example :例子 :

a = [{:a=>1},{:a=>10},{:b=>8},{:c=>7},{:c=>2}]

How to get result like this?如何得到这样的结果?

a = [{:a=>[1, 10]},{:b=>8},{:c=>[7, 2]}]

Try尝试

a.flat_map(&:entries)
  .group_by(&:first)
  .map{|k,v| Hash[k, v.map(&:last)]}

Another alternative:另一种选择:

a = [{:a=>1},{:a=>10},{:b=>8},{:c=>7},{:c=>2}]

p a.each_with_object({}) { |h, o| h.each { |k,v| (o[k] ||= []) << v } }
# => {:a=>[1, 10], :b=>[8], :c=>[7, 2]}

It also works when the Hashes have multiple key/value combinations, eg:当哈希具有多个键/值组合时,它也适用,例如:

b = [{:a=>1, :b=>5, :x=>10},{:a=>10, :y=>2},{:b=>8},{:c=>7},{:c=>2}]
p b.each_with_object({}) { |h, o| h.each { |k,v| (o[k] ||= []) << v } }
# => {:a=>[1, 10], :b=>[5, 8], :x=>[10], :y=>[2], :c=>[7, 2]}

Minor addition to answer by Arie Shaw to match required answer: Arie Shaw 对答案的小补充以匹配所需的答案:

a.flat_map(&:entries)
  .group_by(&:first)
  .map{|k,v| Hash[k, v.size.eql?(1) ? v.last.last : v.map(&:last) ]}
#=> [{:a=>[1, 10]}, {:b=>8}, {:c=>[7, 2]}]

I'd do :我会做 :

a = [{:a=>1},{:a=>10},{:b=>8},{:c=>7},{:c=>2}]
merged_hash = a.each_with_object({})  do |item,hsh|
  k,v = item.shift
  hsh[k] = hsh.has_key?(k) ? [ *Array( v ), hsh[k] ] : v
end

merged_hash.map { |k,v| { k => v } }
# => [{:a=>[10, 1]}, {:b=>8}, {:c=>[2, 7]}]

update更新

A better taste :更好的味道:

a = [{:a=>1},{:a=>10},{:b=>8},{:c=>7},{:c=>2}]
merged_hash = a.each_with_object({})  do |item,hsh|
  k,v = item.shift
 (hsh[k] ||= []) << v
end

merged_hash.map { |k,v| { k => v } }
# => [{:a=>[10, 1]}, {:b=>8}, {:c=>[2, 7]}]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM