How to traverse a Map in Scala (for loop, foreach)

This is an excerpt from the 1st Edition of the Scala Cookbook (#ad) (partially modified for the internet). This is Recipe 11.18, “How to Traverse a Map in Scala

Problem

You want to iterate over the elements in a Scala Map, such as to print all of the key and value elements in the Map.

Solution: Looping over Map values

There are several different ways to iterate over the elements in a Map. Given a sample Map:

val ratings = Map(
    "Lady in the Water"-> 3.0, 
    "Snakes on a Plane"-> 4.0, 
    "You, Me and Dupree"-> 3.5
)

my preferred way to loop over all of the map elements is with this for loop syntax:

for ((k,v) <- ratings) println(s"key: $k, value: $v")

Looping with “foreach”

Using a match expression with the foreach method is also very readable:

ratings.foreach {
    case(movie, rating) => println(s"key: $movie, value: $rating")
}

The following approach shows how to use the Tuple syntax to access the key and value fields of the Map:

ratings.foreach(x => println(s"key: ${x._1}, value: ${x._2}"))

If you just want to use the keys in the map, the keys method returns an Iterable you can use:

ratings.keys.foreach((movie) => println(movie))

For simple examples like this, that expression can be reduced as follows:

ratings.keys.foreach(println)

In the same way, use the values method to iterate over the values in the map:

ratings.values.foreach((rating) => println(rating))

Note: Those are not my movie ratings. They are taken from the book, Programming Collective Intelligence (#ad) (O’Reilly), by Toby Segaran.

Operating on Map values (mapValues, transform)

If you want to traverse the Map to perform an operation on its values, the mapValues method may be a better solution. It lets you perform a function on each map value, and returns a modified Map:

scala> var x = collection.mutable.Map(1 -> "a", 2 -> "b")
x: scala.collection.mutable.Map[Int,String] = Map(2 -> b, 1 -> a)

scala> val y = x.mapValues(_.toUpperCase)
y: scala.collection.Map[Int,String] = Map(2 -> B, 1 -> A)

The transform method gives you another way to create a new Map from an existing Map. Unlike mapValues, it lets you use both the key and value to write a transformation method:

scala> val map = Map(1 -> 10, 2 -> 20, 3 -> 30)
map: scala.collection.mutable.Map[Int,Int] = Map(2 -> 20, 1 -> 10, 3 -> 30)

scala> val newMap = map.transform((k,v) => k + v)
newMap: map.type = Map(2 -> 22, 1 -> 11, 3 -> 33)

See Also