Counting backwards
A for loop does not have to count up. If you start at the high end, subtract in the update and test with a "greater than" comparison, the loop counts down. Reverse loops are useful whenever the order matters: a countdown, the last items first, or a walk from the end of an array to its start.
The three changes
Compared with a counting-up loop, three parts of the header change:
for (let i = 7; i > 2; i--) {
console.log(i);
}
7
6
5
4
3
- Initialization:
let i = 7starts at the largest value. - Condition:
i > 2keeps going whileiis above 2, so the last value printed is 3. Writingi >= 3gives the same loop. - Iteration:
i--subtracts 1 after each pass. It is the opposite ofi++, andi -= 1does the same.
The comparison flips from < to > because the counter now approaches its limit from above. Keeping the old < would give a loop that never runs: 7 < 2 is false at the first check.
Negative numbers
Counting down through zero needs no special handling. Numbers below zero behave like any others, and the loop variable can be negative:
for (let i = 2; i >= -2; i--) {
console.log(i);
}
This prints 2, 1, 0, -1 and -2. The same comparison works on both sides of zero, so there is no need to split the loop into a positive and a negative part.
The exercise
The task is to print every number from 5 down to -5, in decreasing order. That is 11 numbers: 5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5.
- Start at the top. Declare
iwithletand the typenumber, and start it at 5. - Keep going while
i >= -5. Using>=rather than>is what lets -5 itself be printed. The negative sign belongs to the number, so the comparison reads "at least -5". - Decrease by 1 with
i--. - Print
iinside the body withconsole.log.
The solution in TypeScript
for (let i: number = 5; i >= -5; i--) {
console.log(i);
}
After the pass that prints -5, the update makes i equal to -6, the condition -6 >= -5 is false, and the loop ends. The count of lines is first minus last, plus one: 5 - (-5) + 1 = 11.
Looping over an array backwards
The same pattern walks an array from its last element to its first. The last valid index is length - 1, and the first is 0:
const letters: string[] = ["a", "b", "c"];
for (let i = letters.length - 1; i >= 0; i--) {
console.log(letters[i]);
}
This prints c, b and a. A start of letters.length would be one too high: the first pass would read an index past the end of the array, and TypeScript would give undefined without complaint.
Common mistakes
- Using
i++in a countdown. The counter then moves away from the limit and the condition stays true forever. - Keeping the old comparison.
i <= -5is false from the start for a start value of 5, so nothing is printed. - Stopping one step early. With
i > -5the output ends at -4. The task says "through -5", so -5 must be included. - Mixing up the order of the bounds. A reverse loop starts at the large value and ends at the small one. Reading the header aloud helps: "start at 5, keep going while at least -5, subtract 1 each time."
Key takeaways
- To count down, start high, use
>or>=in the condition and subtract in the update. - The loop works the same way across zero and with negative numbers.
- Use
>=when the lowest value must be included. - For an array, a reverse loop starts at
length - 1and ends at index 0.