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

Ruby 合并两个哈希数组,同时保留所有不同的值,ruby,arrays,hash,merge,Ruby,Arrays,Hash,Merge,我想将两个哈希数组合并到一个新数组中: array1 = [{"Name1" => {gender: 'female', nationality: ['german', 'danish']}}] array2 = [{"Name1" => {gender: 'male', nationality: ['german', 'austrian']}}] 这就是我想要的结果: new_array = [{"Name1" => {gender: ['female', 'male'],

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

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文档中找到的唯一合并选项是用另一个散列覆盖重复项。那么如何实现所需的版本呢?

您可以将可选块参数传递给。将为重复的键调用该块。在中,使用块的返回值,而不是被覆盖

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"]}}]

您可以将可选块参数传递给。将为重复的键调用该块。在中,使用块的返回值,而不是被覆盖

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"]}}]
递归方式:

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"]}}
递归方式:

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"]}}

Array(o)
将o转换为[o]并保留[o]只是[o]谢谢你的回答。如果要获取hash_键('Name1')而不是硬编码,您将如何组合该操作?我需要循环浏览它们,而不是手动输入每一个。@steenslag,谢谢您的评论。我更新了答案以使用
Array
函数。@Severin,使用另一个
merge
调用merge
array1[0]
array2[0]:
new_Array=[array1[0]。merge(array2[0]){k,o,n | o.merge(n){k,o,n | Array(o){Array(o)}
数组(o)
将o转换为[o]谢谢你的回答。如果要获取hash_键('Name1')而不是硬编码,您将如何组合该操作?我需要循环浏览它们,而不是手动输入每一个。@steenslag,谢谢您的评论。我更新了答案以使用
Array
函数。@Severin,使用另一个
merge
调用merge
array1[0]
array2[0]:
new_数组=[array1[0]。merge(array2[0]){| k,o,n | o.merge(n){k,o,n | Array(o)}