DEV Community

Adam Cervenka
Adam Cervenka

Posted on

4 1

Scala Tip: mapValues may not do what you expect

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)
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

Heroku

Simplify your DevOps and maximize your time.

Since 2007, Heroku has been the go-to platform for developers as it monitors uptime, performance, and infrastructure concerns, allowing you to focus on writing code.

Learn More

Top comments (0)

Heroku

This site is powered by Heroku

Heroku was created by developers, for developers. Get started today and find out why Heroku has been the platform of choice for brands like DEV for over a decade.

Sign Up

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay