scaladictionaryintegerassignmutablemap

How to increment an Int value in a Map with getOrElseUpdate?


I can update a mutable.Map value with +=:

scala> val map = mutable.Map[Int,Int]()
map: scala.collection.mutable.Map[Int,Int] = Map()

scala> map(5) = 5

scala> map
res55: scala.collection.mutable.Map[Int,Int] = Map(5 -> 5)

scala> map(5) += 1

scala> map
res57: scala.collection.mutable.Map[Int,Int] = Map(5 -> 6)

But I can't use += with getOrElseUpdate and I don't understand why:

scala> map.getOrElseUpdate(5, 0) += 1
<console>:16: error: value += is not a member of Int
  Expression does not convert to assignment because receiver is not assignable.
map.getOrElseUpdate(5, 0) += 1
                          ^

I know I've used a mutable.SortedMap with mutable.ArrayBuffer values before and it let me use that type's += operation with getOrElseUpdate with no problem. Is there something like mutable.Int that I'm supposed to use?


Solution

  • In scala you don't get semantics of obtaining "reference" of a variable and it is because good style of scala is when you don't mutate variables on your own, so you can't do this in this way. Rather than this you can describe mutation with function rather than directly mutating variable in this way:

      import scala.collection.mutable
      val map = mutable.Map.empty[Int,Int]
      val yourKey: Int = ???
      map.updateWith(yourKey){
        case Some(i) => Some(i+1)
        case None => Some(1)
      }
    

    Here i used this: https://www.scala-lang.org/api/2.13.6/scala/collection/mutable/Map.html#updateWith(key:K)(remappingFunction:Option[V]=%3EOption[V]):Option[V]

    Also +, += and +: functions in array buffer and other mutable collections have other semantics.