Reputation: 8835
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)
Upvotes: 6
Views: 2259
Reputation: 81
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}
Upvotes: 0
Reputation: 7882
Similar to previous answer, but without JVM specific API:
additionalMap.forEach { (k, v) -> originMap[k] = (originMap[k] ?: 0) + v }
Upvotes: 1
Reputation: 29844
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)]
Upvotes: 7
Reputation: 31710
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
.
Upvotes: 3