英文:
In Kotlin: What is an elegant way to sum two values of a common key from two maps?
问题
我有一个现有的地图,保存着简单的整数值。我想通过一个给定的地图的值来更新这个现有的地图,该地图保存着可能的键之一。
val originMap = mutableMapOf("Foo" to 10, "Bar" to 5)
val additionalMap = mapOf("Foo" to 4)
// 有疑问的逻辑
assertThat(originMap).containsEntry("Foo", 14)
英文:
I have an existing map that holds simple integer values. I'd like to update that existing map by the value of a given map that holds one of the possible keys.
val originMap = mutableMapOf("Foo" to 10, "Bar" to 5)
val additionalMap = mapOf("Foo" to 4)
// questioned logic
assertThat(originMap).containsEntry("Foo", 14)
答案1
得分: 5
你可以像这样做:
val mergedMap = (originMap.toList() + additionalMap.toList())
.groupBy({ it.first }, { it.second })
.map { (key, values) -> key to values.sum() }
.toMap()
println(mergedMap) // [(Foo, 14), (Bar, 5)]
英文:
You could do it like that:
val mergedMap = (originMap.toList() + additionalMap.toList())
.groupBy({ it.first }, { it.second })
.map { (key, values) -> key to values.sum() }
.toMap()
println(mergedMap) // [(Foo, 14), (Bar, 5)]
答案2
得分: 3
如果您想要原地使用originMap,而不是声明一个新的Map,您可以通过forEach的副作用将additionalMap合并到其中:
additionalMap.forEach { (k, v) -> originMap.merge(k, v, Int::plus) }
// 输出 {Foo=14, Bar=5}
这将从additionalMap中获取每个键(k)和值(v),并使用Int::plus将其添加到originMap中的值。
英文:
If you want to use originMap in-place rather than declaring a new Map, you can merge addtionalMap into it via a side-effect of forEach:
additionalMap.forEach { (k, v) -> originMap.merge(k, v, Int::plus) }
// Prints {Foo=14, Bar=5}
This will take every key (k) and value (v) from additionalMap and add it to the value in originMap using Int::plus.
答案3
得分: 1
与之前的答案类似,但没有JVM特定的API:
additionalMap.forEach { (k, v) -> originMap[k] = (originMap[k] ?: 0) + v }
英文:
Similar to previous answer, but without JVM specific API:
additionalMap.forEach { (k, v) -> originMap[k] = (originMap[k] ?: 0) + v }
答案4
得分: 0
以上解决方案存在一个轻微的错误,它会将所有在 additionalMap 中存在但在 originalMap 中不存在的额外键添加到结果中。
意思是下面的代码会产生如下输出:
val originMap = mutableMapOf("Foo" to 10, "Bar" to 5)
val additionalMap = mapOf("Foo" to 4, "Baz" to 3)
additionalMap.forEach { (k, v) -> if (originMap.containsKey(k)) originMap.merge(k, v, Int::plus) }
// 输出 {Foo=14, Bar=5, Baz=3}
因此,不带有轻微错误的相同解决方案如下:
additionalMap.forEach { (k, v) -> if (originMap.containsKey(k)) originMap.merge(k, v, Int::plus) }
// 输出 {Foo=14, Bar=5}
如果担心特定于 JVM 的 API:则相同的解决方案如下:
additionalMap.forEach { (k, v) -> if (originMap[k] != null) originMap[k] = (originMap[k] ?: 0) + v }
// 输出 {Foo=14, Bar=5}
英文:
The above solution has a minor bug that it will add all additional keys in the additionalMap which are not exists in the originalMap to the result.
Meaning below will produce output like this:
val originMap = mutableMapOf("Foo" to 10, "Bar" to 5)
val additionalMap = mapOf("Foo" to 4, "Baz" to 3)
additionalMap.forEach { (k, v) -> if (originMap.containsKey(k)) originMap.merge(k, v, Int::plus) }
// Prints {Foo=14, Bar=5, Baz=3}
So same solution without the minor bug would be like below:
additionalMap.forEach { (k, v) -> if (originMap.containsKey(k)) originMap.merge(k, v, Int::plus) }
// Prints {Foo=14, Bar=5}
If worried about JVM specific API: then same would be like
additionalMap.forEach { (k, v) -> if (originMap[k] != null) originMap[k] = (originMap[k] ?: 0) + v }
// Prints {Foo=14, Bar=5}
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论