我有两个哈希:
h1 = { "a" => 100, "b" => 200 }
h2 = { "b" => 254, "c" => 300 }
我需要返回哈希,例如:
h3 = {
"a" => { "h1" => 100, "h2" => nil},
"b" => { "h1" => 200, "h2" => 254},
"c" => { "h1" => nil, "h2" => 300}
}
我正在尝试使用:
h1.merge(h2) { |k, val, old| { 'h1' => val, 'h2' => old } }
但它只返回:
{"a"=>100, "b"=>{"h1"=>200, "h2"=>254}, "c"=>300}
没有。 有什么想法吗?
答案 0 :(得分:3)
仅对重复键调用该块。您可以确保两个哈希都包含所有键:
h1 = { "a" => 100, "b" => 200, "c" => nil }
h2 = { "a" => nil, "b" => 254, "c" => 300 }
h1.merge(h2) { |k, val, old| { 'h1' => val, 'h2' => old } }
#=> {"a"=>{"h1"=>100, "h2"=>nil},
# "b"=>{"h1"=>200, "h2"=>254},
# "c"=>{"h1"=>nil, "h2"=>300}}
或者自己构建一个新哈希,例如使用两个哈希的键:
h1 = { "a" => 100, "b" => 200 }
h2 = { "b" => 254, "c" => 300 }
(h1.keys | h2.keys).map { |k| [k, { 'h1' => h1[k], 'h2' => h2[k] }] }.to_h
#=> {"a"=>{"h1"=>100, "h2"=>nil},
# "b"=>{"h1"=>200, "h2"=>254},
# "c"=>{"h1"=>nil, "h2"=>300}}
答案 1 :(得分:2)
如果您阅读了merge
(here)的官方文档,请说:
通过调用块确定每个重复键的值 使用键,其值在hsh中,其值在other_hash中。
这意味着对于密钥"a"
和"c"
,永远不会调用该块(因为它们不是重复键),因此您在结果哈希中缺少nil
。< / p>
你可以试试这个:
h3 = {}
(h1.keys + h2.keys).uniq.each{|a| h3[a] = {"h1" => h1[a], "h2" => h2[a]}}
h3
# => {"a"=>{"h1"=>100, "h2"=>nil}, "b"=>{"h1"=>200, "h2"=>254}, "c"=>{"h1"=>nil, "h2"=>300}}
答案 2 :(得分:1)
这是另一种在哈希和哈希标签数量方面有点笼统的方法:
h1 = { "a" => 100, "b" => 200 }
h2 = { "b" => 254, "c" => 300 }
h3 = { "c" => 111, "b" => 222 }
a = [h1,h2,h3]
labels = {h1=>"h1", h2=>"h2", h3=>"h3"}
h.reduce([]) { |keys,h| keys | h.keys }
.each_with_object({}) { |k,h|
h[k] = a.each_with_object({}) { |f,g| g[labels[f]] = f[k] } }
#=> {"a"=>{"h1"=>100, "h2"=>nil, "h3"=>nil},
# "b"=>{"h1"=>200, "h2"=>254, "h3"=>222},
# "c"=>{"h1"=>nil, "h2"=>300, "h3"=>111}}
步骤:
keys = h.reduce([]) { |keys,h| keys | h.keys }
#=> ["a", "b", "c"]
enum = keys.each_with_object({})
#=> #<Enumerator: ["a", "b", "c"]:each_with_object({})>
k,h = enum.next
#=> ["a", {}]
h[k] = a.each_with_object({}) { |f,g| g[labels[f]] = f[k] }
#=> {"h1"=>100, "h2"=>nil, "h3"=>nil}
k,h = enum.next
#=> ["b", {"a"=>{"h1"=>100, "h2"=>nil, "h3"=>nil}}]
h[k] = a.each_with_object({}) { |f,g| g[labels[f]] = f[k] }
#=> {"h1"=>200, "h2"=>254, "h3"=>222}
k,h = enum.next
#=> ["c", {"a"=>{"h1"=>100, "h2"=>nil, "h3"=>nil},
# "b"=>{"h1"=>200, "h2"=>254, "h3"=>222}}]
h[k] = a.each_with_object({}) { |f,g| g[labels[f]] = f[k] }
#=> {"h1"=>nil, "h2"=>300, "h3"=>111}
h
#=> {"a"=>{"h1"=>100, "h2"=>nil, "h3"=>nil},
# "b"=>{"h1"=>200, "h2"=>254, "h3"=>222},
# "c"=>{"h1"=>nil, "h2"=>300, "h3"=>111}}