Ruby:合并包含数组的哈希

时间:2015-03-06 06:18:40

标签: ruby arrays hash merge

我正在尝试合并两个Hashes。我从here获得了代码。正如您所看到的,我想在我的列表中添加一个爱好。 有很多爱好。当h1形成时,只有一个爱好可用。当第二个爱好到来时,我想将它与之前的哈希合并。

哈希的结构是:

h1 = {"students"=>[{"name"=>"bobby", "hobbies"=>[{"outdoor"=>"cycling"}]}]}

h2 = {"students"=>[{"name"=>"bobby", "hobbies"=>[{"indoor"=>"reading"}]}]}

我运行了这段代码:

res = h1.merge(h2) {|key,val1,val2| val1.merge val2}

我得到的错误是:

 undefined method `merge' for [{"name"=>"bobby", "hobbies"=>[{"outdoor"=>"cycling"}]}]:Array (NoMethodError)

因此,由于涉及阵列,我不知道该怎么做。任何帮助。

必需输出:

{"students"=>[{"name"=>"bobby", "hobbies"=>[{"outdoor"=>"cycling", "indoor"=>"reading"}]}]}

2 个答案:

答案 0 :(得分:4)

内置marge方法无法做到你想要的。 您应该编写原始代码以合并这些结构。

def recursive_merge(h1, h2)
   case h1
   when Hash
      (h1.keys + h2.keys).each do |key|
         if h1.include?(key) && h2.include?(key) then
            recursive_merge(h1[key], h2[key])
         elsif h2.include?(key)
            h1[key] = h2[key]
         end
      end
   when Array
      for i in 0...([h1.count, h2.count].max)
         if i < h1.count && i < h2.count then
            recursive_merge(h1[i], h2[i])
         elsif i < h2.count then
            h1[i] = h2[i]
         end
      end
   end
end

recursive_merge(h1, h2)
puts h1

此方法产生以下输出。 请注意,此方法会覆盖h1本身。

{"students"=>[{"name"=>"bobby", "hobbies"=>[{"outdoor"=>"cycling", "indoor"=>"reading"}]}]}

答案 1 :(得分:2)

您的问题的答案可能是:

h1.merge(h2) { |k, v1, v2| 
  v1.map.with_index { |v1e, idx| 
    v1e['hobbies'].first.merge! v2[idx]['hobbies'].first
    v1e  
  }
  v1 
}

#⇒ {
#  "students" => [
#    [0] {
#      "hobbies" => [
#        [0] {
#           "indoor" => "reading",
#          "outdoor" => "cycling"
#        }
#      ],
#         "name" => "bobby"
#    }
#  ]
# }

但我肯定会重新设计爱好是一个哈希,而不是一个哈希数组,消除了奇怪的first调用:

v1e['hobbies'].merge! v2[idx]['hobbies']

希望它有所帮助。