红宝石。合并嵌套散列而不覆盖 [英] Ruby. Merging a nested hash without overwriting
问题描述
我有一个嵌套的散列:
{
[X,1,2,3] = > {
[X,O,2,3] => {
[X,O,X,3] => [X,O,X,O]
}
}
}
我想合并一个给定的嵌套哈希:
{
[X,1,2,3] => {
[X,O,2,3] => {
[X,O,2,X] => [X,O,O,X]
}
}
}
这样:
{
[X,1, 2,3] => {
[X,O,2,3] => {
[X,O,X,3] => [X,O,X,O],
[X, O,2,X] => [X,O,O,X]
}
}
}
最好的方法是什么?
我将合并的散列在嵌套任意深度具有相同的键,湖。最后一个嵌套散列的值总是与其他所有散列不同。
解决方案如果您确定所有重复键的值是哈希,你可以使用递归 Hash#merge> :
$ p $ def deep_merge(h1,h2)
h1.merge( H2){| K,V1,V2 | deep_merge(v1,v2)}
end
以你为例:
{[X,1,2,3] =>
{[X,O,2,3] =>
{[X,O,X,3] => [X,O,X,O],
[X, O,2,X] => [X,O,O,X]}}}
注意:此方法在一般情况下不起作用,不应用于除问题中定义的结构之外的其他任何内容。它会因 deep_merge({a:1},{a:2})
而失败。
没有关于嵌套键和值的信息:
def deep_merge(h1,h2)
h1.merge( H2){| K,V1,V2 | v1.is_a?(哈希)&& v2.is_a?(哈希)? deep_merge(v1,v2):v2}
end
如果与值冲突不是两个哈希,第二个值都会覆盖第一个。
这两个方法都会返回一个新的散列,并且不会修改h1或h2。
>注意:此方法在 Rails 中可用。
I have a nested hash:
{
["X", 1, 2, 3]=> {
["X", "O", 2, 3]=> {
["X", "O", "X", 3]=>["X", "O", "X", "O"]
}
}
}
I want to merge a given nested hash:
{
["X", 1, 2, 3]=> {
["X", "O", 2, 3]=> {
["X", "O", 2, "X"] => ["X", "O", "O", "X"]
}
}
}
such that:
{
["X", 1, 2, 3]=> {
["X", "O", 2, 3]=> {
["X", "O", "X", 3]=>["X", "O", "X", "O"],
["X", "O", 2, "X"] => ["X", "O", "O", "X"]
}
}
}
What's the best way?
The hashes I'll be merging will have an equivalent key at an arbitrary depth of nested-ness. The value of the last nested hash will always be different from all the other hashes.
If you're sure that all the duplicate keys have values that are Hashes, you can use a recursive Hash#merge with block :
def deep_merge(h1,h2)
h1.merge(h2){|k,v1,v2| deep_merge(v1,v2) }
end
With your example :
{["X", 1, 2, 3]=>
{["X", "O", 2, 3]=>
{["X", "O", "X", 3]=>["X", "O", "X", "O"],
["X", "O", 2, "X"]=>["X", "O", "O", "X"]}}}
NOTE: This method doesn't work in the general case, and shouldn't be used for anything else than the structure defined in the question. It will fail for deep_merge({a:1},{a:2})
.
If you don't have information about the nested keys and values :
def deep_merge(h1,h2)
h1.merge(h2){|k,v1,v2| v1.is_a?(Hash) && v2.is_a?(Hash) ? deep_merge(v1,v2) : v2}
end
In case of a conflict with values that aren't both Hashes, the second value will overwrite the first one.
Both methods return a new hash, and do not modify either h1 or h2.
NOTE: This method is available in Rails.
这篇关于红宝石。合并嵌套散列而不覆盖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!