An idiomatic way to update multiple values ​​in scala.immutable.Map

I need to update (get and increase) two different values, tied to two keys on the map. Sometimes these two keys may coincide. I have the following code:

// 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 block elsewhen key1 == key2, then the value in key1 == key2will be incorrectly increased by 1instead 2--- the second tuple will erroneously update the original value, and not the value used by the first tuple.
Is there a cleaner way to write this?

+3
source share
2 answers

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

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

map(key) map.getOrElse(key, 0).

-, Tuple2. key -> value Tuple2(key, value).

-, if ... then ... else. :

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)
+5

SO- Monoid (ScalaZ):

tailRecFunction(someArg, map |+| Map(key1 -> 1) |+| Map(key2 -> 1))

|+| , .

0

All Articles