我正在努力解决以下任务: 里面有两个包含列表的地图:
def m1 = [ k1: [ l1: ['s1', 's2']]]
def m2 = [ k1: [ l1: ['s3', 's4']]]
因此,我希望将单个地图与列表一起添加。
assert merge(m1, m2) == [ k1: [ l1: ['s1', 's2', 's3', 's4']]]
在实践中,地图要大得多,但想法是一样的。有人可以帮忙吗?
答案 0 :(得分:2)
在groovy控制台中进行了10分钟的试验,结果显示了这段代码:
def m1 = [ k1: [ l1: ['s1', 's2']]]
def m2 = [ k1: [ l1: ['s3', 's4']]]
def accumulator = [:].withDefault{ [:].withDefault{ [] } }
Closure merger
merger = { Map trg, Map m ->
m.each{ k, v ->
switch( v ){
case Map: merger trg[ k ], v; break
case List: trg[ k ].addAll v; break
}
}
}
[ m1, m2 ].each merger.curry( accumulator )
assert [ k1: [ l1: ['s1', 's2', 's3', 's4']]] == accumulator
答案 1 :(得分:1)
以下是我使用Map's collectEntries
method投放的内容。我们使用它两次:第一次找到m2
中存在的需要合并的子地图。第二次找到需要组合的列表值。
def m1 = [ k1: [ l1: ['s1', 's2']], k2: [l2: ['s5', 's6']]] // include entry not in m2
def m2 = [ k1: [ l1: ['s3', 's4']]]
/* Assumes that the maps contain values that support the + operator */
def combineListMaps = { map1, map2 ->
map1.collectEntries { key, list ->
def list2 = map2[key] ?: []
[key, list + list2]
}
}
m1.collectEntries { key, listMap ->
def listMap2 = m2[key]
if (listMap2)
[key, combineListMaps(listMap, listMap2)]
else
[key, listMap]
}