Let\'s say I store bank accounts information in an immutable Map:
val m = Map(\"Mark\" -> 100, \"Jonathan\" -> 350, \"Bob\" -> 65)
Starting Scala 2.13, Map#updatedWith serves this exact purpose:
// val map = Map("Mark" -> 100, "Jonathan" -> 350, "Bob" -> 65)
map.updatedWith("Mark") {
case Some(money) => Some(money - 50)
case None => None
}
// Map("Mark" -> 50, "Jonathan" -> 350, "Bob" -> 65)
or in a more compact form:
map.updatedWith("Mark")(_.map(_ - 50))
Note that (quoting the doc) if the remapping function returns Some(v), the mapping is updated with the new value v. If the remapping function returns None, the mapping is removed (or remains absent if initially absent).
def updatedWith[V1 >: V](key: K)(remappingFunction: (Option[V]) => Option[V1]): Map[K, V1]
This way, we can elegantly handle cases where the key for which to update the value doesn't exist:
Map("Jonathan" -> 350, "Bob" -> 65)
.updatedWith("Mark")({ case None => Some(0) case Some(v) => Some(v - 50) })
// Map("Jonathan" -> 350, "Bob" -> 65, "Mark" -> 0)
Map("Mark" -> 100, "Jonathan" -> 350, "Bob" -> 65)
.updatedWith("Mark")({ case None => Some(0) case Some(v) => Some(v - 50) })
// Map("Mark" -> 50, "Jonathan" -> 350, "Bob" -> 65)
Map("Jonathan" -> 350, "Bob" -> 65)
.updatedWith("Mark")({ case None => None case Some(v) => Some(v - 50) })
// Map("Jonathan" -> 350, "Bob" -> 65)