How to use Scala ‘for’ loops (expressions) with multiple counters (multi-dimensional arrays)

This is an excerpt from the Scala Cookbook (partially modified for the internet). This is Recipe 3.2, “How to use Scala for loops with multiple counters.”

Problem

You want to create a Scala for loop with multiple counters, such as when iterating over a multi‐dimensional array.

Solution

You can create a for loop with two counters like this:

scala> for (i <- 1 to 2; j <- 1 to 2) println(s"i = $i, j = $j")
i = 1, j = 1
i = 1, j = 2
i = 2, j = 1
i = 2, j = 2

When doing this, the preferred style for multiline for loops is to use curly brackets:

for {
    i <- 1 to 2
    j <- 1 to 2
} println(s"i = $i, j = $j")

Similarly, you can use three counters like this:

for {
    i <- 1 to 3
    j <- 1 to 5
    k <- 1 to 10
} println(s"i = $i, j = $j, k = $k")

This is useful when looping over a multidimensional array. Assuming you create a small two-dimensional array like this:

val array = Array.ofDim[Int](2,2)
array(0)(0) = 0
array(0)(1) = 1
array(1)(0) = 2
array(1)(1) = 3

you can print each element of the array like this:

scala> for {
     |     i <- 0 to 1
     |     j <- 0 to 1
     | } println(s"($i)($j) = ${array(i)(j)}")
(0)(0) = 0
(0)(1) = 1
(1)(0) = 2
(1)(1) = 3

Discussion

Ranges created with the <- symbol in for loops are referred to as generators, and you can easily use multiple generators in one loop.

As shown in the examples, the recommended style for writing longer for loops is to use curly braces:

for {
    i <- 1 to 2
    j <- 2 to 3
} println(s"i = $i, j = $j")

This style is more scalable than other styles; in this case, “scalable” means that it continues to be readable as you add more generators and guards to the expression.

See Also