Often in Scala you may need to map over values of Map data structure. You can use the usual map
function, but there is also more concise mapValues
:
Map("a" -> 2).map{ case (k,v) => k -> (v + 2) }
Map("a" -> 2).mapValues(_ + 2)
In many situations the result of these two will be identical, but there is one important difference.
mapValues
doesn't apply the provided function on the value right away. Instead, it creates a view (wrapper) over the data and only evaluates the function when the value is accessed.
This is OK if your code doesn't have any side effects, but if it has, it may cause hard to find issues. For example leaking of exceptions:
scala.util.Try(
Map("a" -> 2).mapValues(v => (throw new RuntimeException))
).isSuccess
// returns true
The newly created map will happily leave the Try
wrapper as success, and the exception will be thrown only when the value is accessed later.
In my opinion, mapValues
name was a poor choice because it seems to suggest the same functionality as map, but only for values. Maybe wrapValues
would be better?
If you want to be more concise, but still have the same semantics as a map
function, you can use transform
:
Map("a" -> 2).transform((k,v) => v + 2)
Top comments (0)