Question:
How to merge the maps while summing up values of common keys among the maps.
Input:
[a: 10, b:2, c:
The first one can be accomplished by:
/* Transform entries in map z by adding values of keys also present in zz
* Take any entries in map zz whose keys are not in z. Add the result.
*/
Map mergeMaps(Map z, Map zz){
Map y = z.inject([:]) { result, e -> zz.keySet().contains(e.key) ? result << [(e.key) : e.value + zz[e.key]] : result << e }
Map yy = zz.findAll { e -> !z.keySet().contains(e.key) }
y + yy
}
Let's use this now at the Groovy console:
mergeMaps([a: 10, b:2, c:3], [b:3, c:2, d:5])
Result: [a:10, b:5, c:5, d:5]
The extended question (more generic) one can be accomplished by a small tweak:
Map mergeMapsWith(Map z, Map zz, Closure cls){
Map y = z.inject([:]) { result, e -> zz.keySet().contains(e.key) ? result << [(e.key) : cls.call(e.value,zz[e.key])] : result << e }
Map yy = zz.findAll { e -> !z.keySet().contains(e.key) }
y + yy
}
Let's use this now at the Groovy console:
mergeMapsWith([a: 10, b:2, c:3], [b:3, c:2, d:5]) { a, b -> Math.min(a,b)}
Result: [a:10, b:2, c:2, d:5]
or if we wanted to merge with a multiplication:
mergeMapsWith([a: 10, b:2, c:3], [b:3, c:2, d:5]) { a, b -> a * b }
Result: [a:10, b:6, c:6, d:5]