Idiomatic way to update multiple values in scala.immutable.Map

dictionary, idioms, scala

Solution

First of all, you can simplify the map to return `0` when no key is present:

val map0 = Map.empty[Int, Int] withDefaultValue 0

Then you can safely call `map(key)` instead of `map.getOrElse(key, 0)`.

Second, you can use the arrow-association syntax to create `Tuple2` instances. I.e. `key -> value` instead of `Tuple2(key, value)`.

Third, I would not introduce the `if ... then ... else` at all. Just update the map for each key successively:

def addKey(map: Map[Int, Int], key: Int) = map + (key -> (map(key) + 1))

val map1 = addKey(map0, key1)
val map2 = addKey(map1, key2)
tailRecFunction(someArg, map2)

Problem

I need to update (retrieve and increase) two different values bound to two keys in a map. The two keys can coincide sometimes. I have the following code for now: ``` // val map: Map[Int, Int] // val key1, key2: Int if (key1 == key2) { tailRecFunction(someArg, map + Tuple2(key1, 2 + map.getOrElse(key1, 0))) } else { tailRecFunction(someArg, map + Tuple2(key1, 1 + map.getOrElse(key1, 0)) + Tuple2(key2, 1 + map.getOrElse(key2, 0))) } ``` As you can see, if you use the `else` block when `key1 == key2`, then the value at `key1 == key2` will incorrectly be increased by `1` instead of `2` --- the second tuple erroneously updates the original value, rather than the value applied by the first tuple. Is there a cleaner way to write this?

Original source

Related problems