while and repeat-while
In the previous lesson the runner knew in advance how many laps to run. Sometimes it goes differently: the coach says "Run until you have done a kilometer." The runner does not work out the number of laps in advance. Before each lap they look at the meter counter and decide whether to start another one.
That is how the while loop works: it repeats its body as long as a condition is true, and it checks the condition before each iteration. Here is that kilometer:
var meters = 0
var laps = 0
while meters < 1000 {
meters += 400
laps += 1
}
print(laps, meters) // 3 1200Let's go through the iterations:
- Before the first lap
metersis0, the condition0 < 1000is true, and the body runs:metersbecomes400,lapsbecomes1. 400 < 1000is true, second lap:800meters and2laps.800 < 1000is true, third lap:1200meters and3laps.1200 < 1000is false, and the loop ends without a new lap.printprints3 1200.
The check comes before the lap
The line while meters < 1000 is built like an if: the word while is followed by a condition of type Bool, and the body sits in braces. You don't need parentheses around the condition.
The key thing about while is the order of events. First the check, then the iteration. The loop ends after the iteration on which the condition became false. That is why meters holds 1200 after the loop, not 1000: the runner does not leave the track in the middle of a lap.
If the condition is false from the very start, the body never runs. With var meters = 2000 the program prints 0 2000 right away.
Here the picture is inaccurate: a real runner steps onto the track at least once, but a while loop may not run the body at all.
The repeat-while loop
Sometimes the body has to run at least once. That is what the repeat-while loop is for: first the lap, then the check. Other languages write this loop with do and while, and in Swift it starts with the word repeat.
Let's compare two loops with the same false condition:
var x = 10
while x < 5 {
x += 1
}
print(x) // 10
repeat {
x += 1
} while x < 5
print(x) // 11Let's go step by step:
while x < 5starts with the check:10 < 5is false, the body does not run, andprintprints10.repeatstarts with the body:xbecomes11.- Only then does
while x < 5check the condition:11 < 5is false, and the loop ends. printprints11: therepeatbody ran exactly once.
A classic task for repeat-while is counting the digits of a number. Each iteration drops the last digit until the number becomes zero:
var number = 2026
var digits = 0
repeat {
digits += 1
number = number / 10
} while number > 0
print(digits) // 4Integer division drops the remainder, so 2026 turns into 202, then into 20, 2 and 0.
Why repeat here and not while? Zero has one digit. With var number = 0 this loop runs the body once, and the program prints 1. A while number > 0 loop with the same body would never run it, and the program would print 0.
Interviewers often ask how while differs from repeat-while. The answer: while checks the condition before the body and may never run it, while repeat-while checks after the body, so the body runs at least once.
Common mistake
The body of the loop never changes the variable from the condition:
var i = 1
while i <= 3 { // ✗
print(i)
}The condition i <= 3 is always true, because i is always 1. The program prints 1 again and again and never stops by itself. Such a loop is called infinite: the runner keeps running laps while the counter stands still.
Stop the program by hand: in a terminal with Ctrl+C, in Xcode with the Stop button. In Swift Playgrounds, the run button becomes a stop button while the program runs. Add i += 1 at the end of the body, and the loop prints 1, 2 and 3.
Key points
whilechecks the condition before each iteration: if it is false from the start, the body never runs.- The loop ends after the iteration on which the condition became false.
repeat-whilechecks the condition after the body, so the body runs at least once.- If the body never changes the variable from the condition, the loop becomes infinite.