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 3includes 3 as the last possible value;by -1subtracts 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.
- 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 is5 to -5 by -1. - Use it in the loop.
for (i <- 5 to -5 by -1)makesitake the values 5, 4, 3, and so on down to -5. - 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 -3gives 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 0fails at run time with anIllegalArgumentExceptionthat says the step cannot be 0. - Negative numbers need no special care. The bounds
5and-5are ordinaryIntvalues.
Common mistakes
- Forgetting
by -1. The range is empty and nothing is printed. - Writing
by 1orby 5on a countdown. A positive step cannot reach a smaller end. - Using
untilby accident.5 until -5 by -1stops at -4, so -5 is missing. - Swapping the bounds.
-5 to 5 by -1is 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. toincludes the end value anduntilexcludes it, in both directions.
