Start learning free

LESSON 127 OF 414 · WHILE LOOPS & FOR LOOPS

Looping in Reverse in Scala: Ranges with a Negative Step

Lesson Read the full explanation

A for loop can also count backwards, as long as we define the right conditions. For example:

for (i <- 7 to 3 by -1) {
	println(i)
}

The output of this code is:

7
6
5
4
3

Let's break down this code:

  • The range starts at 7.

  • to 3 means the range includes 3.

  • by -1 means we decrease our number by 1 every time.


Assignment

Let's print all numbers from 5 through -5 in decreasing order.


Hint
Look at the examples above if you get stuck.


STEP 1 OF 2
    Ctrl + Enter to check

    SCALA · WHILE LOOPS & FOR LOOPS

    Looping In Reverse in Scala, explained

    Counting down with a range

    Ranges count upward by default, so 7 to 3 is empty: it starts at 7, and 7 is already past 3. To count down, give the range a negative step with by:

    for (i <- 7 to 3 by -1) {
        println(i)
    }
    

    The output is 7, 6, 5, 4 and 3, one per line. Reading the range left to right:

    • it starts at 7;
    • to 3 includes 3 as the last possible value;
    • by -1 subtracts 1 each time.

    The loop stops when the next value would go below 3.

    What happens without the step

    If you leave out by -1, the range 7 to 3 has no values, and the loop body never runs. Scala doesn't report an error here: the program prints nothing, which can be confusing. When a countdown prints nothing at all, check that the step is negative.

    Counting down with until

    A negative step works with until too, and then the end value is excluded. 7 until 3 by -1 gives 7, 6, 5 and 4. Use to when the last number should be printed, and until when it should not.

    The assignment: 5 down to -5

    The task is to print every number from 5 through -5 in decreasing order.

    1. Write the range. It starts at 5, ends at -5 and must include -5, so use to. Counting down needs the negative step, so the range is 5 to -5 by -1.
    2. Use it in the loop. for (i <- 5 to -5 by -1) makes i take the values 5, 4, 3, and so on down to -5.
    3. Print the loop variable. Inside the body, println(i) prints one value per line.
    for (i <- 5 to -5 by -1) {
        println(i)
    }
    

    The output is 5, 4, 3, 2, 1, 0, -1, -2, -3, -4 and -5. That is eleven numbers, because zero is part of the sequence.

    Why the order matters

    A range always walks from its start toward its end in the direction of the step. In 5 to -5 by -1 the start is 5 and the step moves left on the number line, so the walk reaches -5. If the step pointed away from the end, the walk could never get there, and Scala represents that as an empty range instead of looping forever.

    Notes on negative steps

    • Other step sizes work. 10 to 1 by -3 gives 10, 7, 4 and 1.
    • The step must match the direction. A positive step with a start above the end gives an empty range, and so does a negative step with a start below the end.
    • A step of 0 is not allowed. 1 to 5 by 0 fails at run time with an IllegalArgumentException that says the step cannot be 0.
    • Negative numbers need no special care. The bounds 5 and -5 are ordinary Int values.

    Common mistakes

    • Forgetting by -1. The range is empty and nothing is printed.
    • Writing by 1 or by 5 on a countdown. A positive step cannot reach a smaller end.
    • Using until by accident. 5 until -5 by -1 stops at -4, so -5 is missing.
    • Swapping the bounds. -5 to 5 by -1 is empty, because the start is already below the end.

    Key takeaways

    • A range counts up unless its step is negative.
    • For a countdown, put the larger number first and add by -1.
    • to includes the end value and until excludes it, in both directions.
    Keep going with ScalaAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free