英文:
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>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论