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

This is an excerpt from the 1st Edition of the Scala Cookbook (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 (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