简体   繁体   中英

In Kotlin: What is an elegant way to sum two values of a common key from two maps?

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)]

Try it here!

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM