Count-Controlled Iteration

Imagine your teacher asks the class to write out the 7 times table, all the way to 7 \times 12. You could type twelve almost-identical lines by hand — but that is slow, dull, and easy to get wrong. Computers are brilliant at exactly this: doing the same thing over and over. Telling a computer to repeat something is called iteration (from a Latin word meaning "to do again").

When you know in advance exactly how many times you want to repeat — twelve times, a hundred times, once for every day of the week — you reach for a count-controlled loop. It has a little counter that starts at some number, counts up by one each go, and stops when it has run the right number of times. In TypeScript (and lots of other languages) this loop is written with the keyword for, so people often just call it a for loop.

The shape of a for loop

Every count-controlled loop has the same three little parts, all squeezed into the brackets after for, separated by semicolons:

\texttt{for (}\underbrace{\texttt{let i = 0}}_{\text{start}}\texttt{;}\; \underbrace{\texttt{i < n}}_{\text{keep going while}}\texttt{;}\; \underbrace{\texttt{i++}}_{\text{step}}\texttt{) \{ \dots \}}

Everything inside the curly braces { } is the body — the work that runs once per count. Watch a counter climb below, then we'll write some real loops.

Your first loop: say hello five times

Here is the whole idea in miniature. Instead of writing console.log five times, we write it once inside a loop that runs five times. Press Run:

for (let i = 0; i < 5; i++) { console.log("Hello! This is pass number " + i); }

Notice the counter i takes the values 0, 1, 2, 3, 4 — five passes, but it stops before 5 because the condition is i < 5. Starting at 0 and stopping before the count is the normal habit in programming; it feels odd at first, but you get used to it fast.

Now think about how much work the loop saved. Ten passes? Change one number. A thousand passes? Still change one number. The loop replaces copy-pasting — and unlike copy-paste it never mistypes a line.

Counting for real

Loops shine when you want to use the counter, not just repeat blindly. Here we print the numbers 1 to 10. To make them come out as 1, 2, \dots, 10 (not 0, \dots, 9) we start the counter at 1 and loop while i <= 10:

for (let i = 1; i <= 10; i++) { console.log(i); }

There are two fair ways to count to ten: start at 0 with i < 10, or start at 1 with i <= 10. Both run the body ten times — you just pick whichever makes your numbers come out right.

A times table

Back to that 7 times table. The counter i runs from 1 to 12, and each pass prints 7 \times i. Change the table value to any number you like and Run it again:

const table: number = 7; for (let i = 1; i <= 12; i++) { console.log(table + " × " + i + " = " + table * i); }

One tiny loop can print the 2 times table, the 7 times table, or the 231 times table — just by changing a single number. That is the power of iteration.

Building up an answer: summing 1 to n

A loop can also add things up as it goes. We keep a running total in a variable (often called an accumulator) that starts at 0, and each pass adds the current counter to it. By the end, the total holds 1 + 2 + \dots + n:

const n: number = 100; let total: number = 0; for (let i = 1; i <= n; i++) { total = total + i; // add this number onto the running total } console.log("The sum of 1 to " + n + " is " + total);

The computer happily added a hundred numbers in a blink. Try changing n to 1000 — it's just as fast, and you certainly wouldn't want to do that by hand.

Legend has it that when the mathematician Carl Friedrich Gauss was a boy, his teacher told the class to add up every number from 1 to 100, expecting a long, quiet lesson. Gauss answered in seconds: 5050. He'd spotted that the numbers pair up — 1 + 100, 2 + 99, 3 + 98, … — each pair making 101, and there are 50 pairs, so 50 \times 101 = 5050. The general formula is \tfrac{n(n+1)}{2}. The loop and the formula give the same answer — a lovely reminder that a clever bit of thinking can sometimes beat brute repetition.

When not to use a count-controlled loop

A for loop is the right tool when you know the number of repeats before the loop starts — "do this 12 times", "once for each of the 30 pupils". But sometimes you don't know the count in advance: "keep asking for a password until it's correct", or "keep rolling the dice until you get a six". Those are condition-controlled loops (usually a while loop), and they're a story for another page. The key question to ask yourself is simply: do I know how many times, up front? If yes, count.

The most famous loop bug in all of programming is the off-by-one error — running the loop one time too many, or one time too few. It almost always comes down to two small choices: where you start (0 or 1) and which comparison you use (< or <=).

Suppose you want to print exactly five stars. This loop prints six, because starting at 0 and using <= lets i take the values 0,1,2,3,4,5 — that's six numbers:

for (let i = 0; i <= 5; i++) { // BUG: prints ★ six times, not five! console.log("★"); }

Two safe combinations both give exactly n passes:

Mixing them up (start at 0 but use <=) is the classic off-by-one. When a loop does one too many or one too few, this is the first thing to check.