Start learning free

LESSON 188 OF 414 · NESTED LOOPS

Nested Loops in Scala: for Loops Inside for Loops

Lesson Read the full explanation

A nested loop has one loop inside of another. These are typically used for working with two dimensions such as printing stars in rows and columns as shown below. When a loop is nested inside another loop, the inner loop runs many times inside the outer loop. In each iteration of the outer loop, the inner loop will be re-started. The inner loop must finish all of its iterations before the outer loop can continue to its next iteration.

Example:

for (row <- 0 until 3) {
	for (col <- 0 until 5) {
		print("*")
	}
    println()
}

// This code prints a rectangle with 3 rows and 5 columns, filled with '*'

Iterating through multidimensional arrays

Nested loops are also helpful when we want to iterate through a multi dimensional array, for example:

val arr = Array(Array(1, 2), Array(3, 4), Array(5, 6))

for (i <- arr.indices) {
	for (j <- arr(i).indices) {
		println(arr(i)(j))
	}
}

This outputs each sub-element in arr one at a time. Note that for the inner loop, we are using the indices of arr(i), since arr(i) is itself an array.

Breaking nested loops

Scala has no break keyword (the library offers scala.util.control.Breaks, but it is rarely needed). A common beginner-friendly approach is to put the work behind an if condition:

val arr = Array(Array(1, 2), Array(3, 4), Array(5, 6))

for (i <- arr.indices) {
	for (j <- arr(i).indices) {
		if(arr(i)(j) != 3 && arr(i)(j) != 4) {
			println(arr(i)(j))
		}
	}
}

// prints the numbers 1, 2, 5 and 6 on different lines

When the value is 3 or 4, the body of the if does not run, so those values are skipped.


Assignment
Follow the Coding Tutorial and let's write some nested loops.


Hint
Look at the examples above if you get stuck.


STEP 1 OF 4
    Ctrl + Enter to check

    SCALA · NESTED LOOPS

    Nested Loops in Scala, explained

    What a nested loop is

    A nested loop is a loop inside another loop. The outer loop starts one pass, and the inner loop then runs from start to finish before the outer loop moves on to its next pass. On each new outer pass the inner loop starts over.

    That makes nested loops the natural tool for anything with two dimensions: rows and columns of a picture, a table, an array of arrays, or every pair of elements in a collection.

    The syntax

    In Scala a for loop over a range reads "for each value in this range". 0 until 3 gives 0, 1 and 2 and leaves out the upper end, while 0 to 3 includes 3.

    for (row <- 0 until 3) {
        for (col <- 0 until 5) {
            print("*")
        }
        println()
    }
    
    *****
    *****
    *****
    

    The pieces:

    • print("*") writes text and stays on the same line.
    • println() with no argument ends the current line.
    • The inner loop's closing brace comes before println(), so a newline is printed once per row and not once per star.

    The inner body runs 3 × 5 = 15 times in total. In general, if the outer loop runs a times and the inner loop runs b times per pass, the inner body runs a * b times. This count is what makes nested loops costly on large inputs.

    The inner range can depend on the outer variable

    The inner loop doesn't have to run the same number of times on every pass:

    for (row <- 1 to 4) {
        for (col <- 1 to row) {
            print("*")
        }
        println()
    }
    
    *
    **
    ***
    ****
    

    Looping through an array of arrays

    A two-dimensional array in Scala is an array whose elements are arrays. Elements are read with parentheses, not square brackets:

    val arr = Array(Array(1, 2), Array(3, 4), Array(5, 6))
    
    for (i <- arr.indices) {
        for (j <- arr(i).indices) {
            println(arr(i)(j))
        }
    }
    

    This prints 1, 2, 3, 4, 5 and 6, one per line. arr.indices is the range of valid positions, 0 until arr.length. The inner loop uses arr(i).indices because arr(i) is itself an array, and rows may have different lengths. arr(i)(j) picks row i, then element j inside it.

    Skipping values and stopping early

    To skip some elements, put the work behind an if:

    for (i <- arr.indices) {
        for (j <- arr(i).indices) {
            if (arr(i)(j) != 3 && arr(i)(j) != 4) {
                println(arr(i)(j))
            }
        }
    }
    

    This prints 1, 2, 5 and 6. When the value is 3 or 4 the condition is false, so the body is skipped, but both loops continue.

    Scala has no break statement in the language itself. If you need to stop a loop early, the usual approach is a while loop with a flag you check in its condition. The standard library also has scala.util.control.Breaks, with breakable and break(), but you won't need it in this lesson.

    Several loops in one for

    Scala can put both ranges into a single for, separated by a semicolon:

    for (r <- 1 to 3; c <- 1 to 3) {
        print(r * c + " ")
    }
    

    This prints 1 2 3 2 4 6 3 6 9 . It is the same as nesting two loops, with the second changing fastest. A separate nested loop is still the clearer choice when you need something to happen after the inner loop, such as the println() above.

    The exercise, step by step

    The task is to print a rectangle of stars with 5 rows and 10 columns.

    1. The outer loop. Write for (row <- 0 until 5). One pass per row, and 0 until 5 gives the five values 0 to 4.
    2. The inner loop. Inside it, write for (col <- 0 until 10). One pass per column. Its body will run 5 × 10 = 50 times.
    3. Print a star. Inside the inner loop, call print("*"), with no newline, so the 10 stars of one row share a line.
    4. End the row. After the inner loop but still inside the outer one, call println(). The next row starts on a new line.
    for (row <- 0 until 5) {
        for (col <- 0 until 10) {
            print("*")
        }
        println()
    }
    

    The output is five lines of ten stars:

    **********
    **********
    **********
    **********
    **********
    

    Common mistakes

    • Putting println() inside the inner loop. Every star lands on its own line, giving 50 lines with one star each.
    • Leaving println() out. All 50 stars end up on one line.
    • Mixing up until and to. 0 until 5 runs 5 times; 0 to 5 runs 6 times.
    • Reusing one variable name. Naming both loop variables i hides the outer one inside the inner loop. Use distinct names such as row and col.
    • Using square brackets. arr[i][j] doesn't work in Scala; write arr(i)(j).

    Key takeaways

    • The inner loop runs completely on every pass of the outer loop, so the inner body runs outer * inner times.
    • print keeps the line open and println() ends it.
    • For an array of arrays, loop over arr.indices and then arr(i).indices, and read elements as arr(i)(j).
    Keep going with ScalaAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free