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)
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)]
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
.
与之前的答案类似,但没有 JVM 特定的 API:
additionalMap.forEach { (k, v) -> originMap[k] = (originMap[k] ?: 0) + v }
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}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.