合并两个哈希数组,同时保留所有不同的值

时间:2014-03-22 19:11:34

标签: ruby arrays hash merge

我想将两个哈希数组合并到一个新数组中:

array1 = [{"Name1" => {gender: 'female', nationality: ['german', 'danish']}}]
array2 = [{"Name1" => {gender: 'male', nationality: ['german', 'austrian']}}]

现在这是我要找的结果:

new_array = [{"Name1" => {gender: ['female', 'male'], nationality: ['german', 'danish', 'austrian']}}]

我在Ruby文档中找到的唯一合并选项会用另一个哈希覆盖重复项。那么我怎样才能达到我需要的版本呢?

2 个答案:

答案 0 :(得分:3)

您可以将可选块参数传递给Hash#merge。为重复的密钥调用该块。 in使用块的返回值而不是被覆盖。

array1 = [{"Name1" => {gender: 'female', nationality: ['german', 'danish']}}]
array2 = [{"Name1" => {gender: 'male', nationality: ['german', 'austrian']}}]

new_array = [{'Name1' => array1[0]['Name1'].merge(array2[0]['Name1']) { |k,o,n|
  Array(o) | Array(n)
}}]
# => [{"Name1"=>
#       {:gender=>["female", "male"],
#        :nationality=>["german", "danish", "austrian"]}}]

答案 1 :(得分:1)

递归方式:

array1 = [{"Name1" => {gender: 'female', nationality: ['german', 'danish']}}]
array2 = [{"Name1" => {gender: 'male', nationality: ['german', 'austrian']}}]

def merge_recur(ar1,ar2)
  (ar1+ar2).inject do |h1,h2|
    h1.merge(h2) do |k,o,n|
      if o.is_a?(Hash) and n.is_a?(Hash)
        merge_recur([o],[n])
      elsif o.is_a?(Array) and n.is_a?(Array)
        o | n
      else
        [o,n]
      end
    end
  end
end

merge_recur(array1,array2)
# => {"Name1"=>
#      {:gender=>["female", "male"],
#       :nationality=>["german", "danish", "austrian"]}}