我有两张地图:
firstMap = [totalProjectCount:53, activeProjectCount:29, completedProjectCount:1, userCount:85]
secondMap = [totalProjectCount:48, activeProjectCount:41, completedProjectCount:0, userCount:123]
我需要结果如:
resultMap = [totalProjectCount:101, activeProjectCount:70, completedProjectCount:1, userCount:208]
答案 0 :(得分:4)
又一个Groovy替代方案:
def firstMap = [totalProjectCount:53, activeProjectCount:29, completedProjectCount:1, userCount:85, a:1]
def secondMap = [totalProjectCount:48, activeProjectCount:41, completedProjectCount:0, userCount:123, b:2]
def result = [firstMap, secondMap]*.keySet().flatten().toSet().collectEntries { k ->
[k, (firstMap[k] ?: 0) + (secondMap[k] ?: 0)]
}
assert result == [a:1, b:2, completedProjectCount:1, userCount:208, activeProjectCount:70, totalProjectCount:101]
如果一个地图中的值在另一个地图中不存在,则此功能也有效(请参阅a
和b
)
答案 1 :(得分:3)
要使其成为工具带的可重复使用部分,重要的是提取要合并的功能。
然后合并本身只是创建一个新地图,其中包含地图的所有键,并且通过传递的函数减少了值。
Map mergeWith(Closure fn, Map... maps) {
maps*.keySet().sum().collectEntries{k->
[k, maps.findAll{it.containsKey k}*.get(k).inject(fn)]
}
}
def m1 = [a:53, b:29, c:1, x:85]
def m2 = [a:48, b:41, c:0, y:123]
def m3 = [z:42]
// sum
assert mergeWith({a,b->a+b}, m1, m2, m3)==[a:101, b:70, c:1, x:85, y:123, z:42]
// product
assert mergeWith({a,b->a*b}, m1, m2, m3)==[a:2544, b:1189, c:0, x:85, y:123, z:42]
mergeWith
采用缩减函数(一个被调用的函数)
两个参数并返回一个值)和一些地图。这意味着,你可以a)
将它用于除了总和之外的其他操作,b)你可以使用它
不止一张地图。
maps*.keySet().sum()
是所有键的并集。然后我们
在这组键上collectEntries
(构建新地图)。对于价值
找到包含密钥的所有地图(这使得这项工作很顺利
在实际值为false的情况下)并获取k
的值
通过传播运营商。然后我们减少(奇怪地命名为inject
)列表
传递函数的值。
答案 2 :(得分:2)
Map additionJoin( Map firstMap, Map secondMap )
{
def resultMap = [:];
resultMap.putAll( firstMap );
resultMap.putAll( secondMap );
resultMap.each { key, value ->
if( firstMap[key] && secondMap[key] )
{
resultMap[key] = firstMap[key] + secondMap[key]
}
}
return resultMap;
}
def firstMap = [totalProjectCount:53, activeProjectCount:29, completedProjectCount:1, userCount:85]
def secondMap = [totalProjectCount:48, activeProjectCount:41, completedProjectCount:0, userCount:123]
def resultMap = additionJoin( firstMap , secondMap )
println resultMap
答案 3 :(得分:1)
试试这个:
Map<String, Integer> resultMap = new HashMap<>(firstMap);
secondMap.forEach((k, v) -> resultMap.merge(k, v, Integer::sum));
答案 4 :(得分:1)
更有效率,你可以写如下:
Map additionJoin(Map firstMap, Map secondMap)
{
secondMap.each { key, value ->
if( firstMap[key])
{
firstMap[key] = firstMap[key] + secondMap[key]
}
}
return firstMap;
}
def firstMap = [totalProjectCount:53, activeProjectCount:29, completedProjectCount:1, userCount:85]
def secondMap = [totalProjectCount:48, activeProjectCount:41, completedProjectCount:0, userCount:123]
def resultMap additionJoin( firstMap , secondMap )
println resultMap
这将是高性能,因为它将使用第三张地图保存。
此外,如果您通过引用了解价值,您也可以像下面这样做:
void additionJoin(Map firstMap, Map secondMap)
{
secondMap.each { key, value ->
if( firstMap[key])
{
firstMap[key] = firstMap[key] + secondMap[key]
}
}
}
def firstMap = [totalProjectCount:53, activeProjectCount:29, completedProjectCount:1, userCount:85]
def secondMap = [totalProjectCount:48, activeProjectCount:41, completedProjectCount:0, userCount:123]
additionJoin( firstMap , secondMap )
println firstMap
虽然后来的解决方案妨碍了可读性(有自以为是的观点),可以通过以下附加声明来实现:
def resultMap = firstMap
希望它可以帮助你有效地做同样的事情。