Groovy映射合并



问题:如何合并具有相同键集但不同值的两个groovy映射。

示例:

Map one = [ 'a': ['foot':'ball'],
'b': 'cricket',
'c': 'tennis'
]
Map two = ['a': ['basket':'ball']]

我想要的输出是:

Map three = [ 'a': ['foot':'ball', 
'basket': 'ball'],
'b': 'cricket',
'c': 'tennis'
]

因此,如上所述,它需要选择任何匹配的键,并合并这些键的值,从而生成组合映射。

提前谢谢。

可能有一种稍短的方法可以做到这一点,但它非常简洁:

Map three = [:]
(one.entrySet() + two.entrySet()).each { entry -> 
three[entry.key] = three.containsKey(entry.key) ? [:] << three[entry.key] << entry.value : entry.value 
}
println three

并产生所需的结果:

[a:[foot:ball, basket:ball], b:cricket, c:tennis]

不是最短的,但合并地图的好方法:

Map merge(Map left, Map right) {
[right.findAll { k, _ -> !left.containsKey(k) },
left.findAll { k, _ -> !right.containsKey(k) },
left.findAll { k, _ -> right.containsKey(k) }
.collectEntries { k, v -> [v, right[k]].every { it instanceof Map }
? [k, merge(v, right[k])]
: [k, right[k]] // this is where you define the actual merge behavior 
// in this case: righ precedes left
}
].collectMany { Map it -> it.entrySet() }.collectEntries()
}

这种方法不仅处理嵌套更深的映射,而且还处理仅在其中一个映射中的键。如果两个映射的嵌套结构不相同,我见过许多解决方案失败。以下是的一些测试用例

assert merge([a:1], [a:2]) == [a:2]
assert merge([a:[b:1]], [a:2]) == [a:2]
assert merge([a:[b:1], c:1], [a:[b:2], c:2]) == [a:[b:2], c:2]
assert merge([a:1], [b:2]) == [a:1, b:2]
assert merge([a:[b:[c:[d:1]]]], [a:[b:[c:[e:2]]]]) == [a:[b:[c:[d:1, e:2]]]]

最新更新