合并散列和推送值而不重置它们

时间:2015-06-02 17:30:10

标签: ruby

问题如下:

我有一个类似下面的哈希:

hash = {test: [123]}

我可能需要添加到此哈希,所以我使用merge!

hash.merge!({test2: [345]})

给了我:

{test: [123], test2: [345]}

但现在如果我尝试将另一个哈希合并到:

{test: [999]}

我在测试时丢失了之前的值:并获取

{test: [999], test2: [345]}

而不是我想要的:

{test: [123, 999], test2: [345]}

我知道如何通过一种解决方法来解决这个问题,这种解决方法在1-2个案例中失败了......希望以不同的方式解决某些人的大脑来解决这个问题

2 个答案:

答案 0 :(得分:2)

你需要:

# I just considered if values are not array before hand.
hash.merge!(new_hash) { |_, o, n| [o, n].flatten.uniq }
# if you want to keep both old and new inside the array even if
# they are same, do
hash.merge!(new_hash) { |_, o, n| [o, n].flatten }

答案 1 :(得分:0)

这是另一种方法:

hash = { test: [123] }
arr = [{ test2: [345] }, { test: [999] },
       { test: [123] }, { test2: ['cat','dog'] }]

arr.each_with_object(hash) do|g,h|
   k,v = g.first
   h[k] = (h[k] || []).concat(v)
end
  #=> {:test=>[123, 999, 123], :test2=>[345, "cat", "dog"]} 

如果您不想改变hash

[hash, *arr].each_with_object({}) do|g,h|
   k,v = g.first
   h[k] = (h[k] || []).concat(v)
end
  #=> {:test=>[123, 999, 123], :test2=>[345, "cat", "dog"]} 
hash
  #=> {:test=>[123]} 

[hash,*arr].flat_map(&:to_a).
            group_by(&:first).
            values.
            each_with_object({}) do |a,h|
              h[a.first.first] = a.flat_map(&:last)
            end
  #=> {:test=>[123, 999, 123], :test2=>[345, "cat", "dog"]} 
hash
  #=> {:test=>[123]}