for Loops
Printing the café menu means doing the same thing for every drink. Writing one println per drink breaks the day the menu changes. A loop repeats the work once per item, however many items there are.
The rule
for walks through things; it does not count by itself.
Kotlin's for takes each element of something iterable, one at a time:
val drinks = listOf("latte", "mocha", "chai")
for (drink in drinks) {
println(drink)
}There is no C-style loop like for (i = 0; i < 3; i++). When you need numbers, walk through a range:
for (i in 1..3) print(i) // 123
for (i in 0 until drinks.size) println(drinks[i])
for (i in drinks.indices) println(drinks[i]) // same, safer
for (i in 10 downTo 0 step 5) print("$i ") // 10 5 0drinks.indices is the range 0..size - 1, so it can never step off the end.
When you want both the position and the item, use withIndex() and unpack the pair:
for ((i, drink) in drinks.withIndex()) {
println("${i + 1}. $drink") // 1. latte, 2. mocha, 3. chai
}Maps unpack into key and value:
val prices = mapOf("latte" to 3.5, "mocha" to 4.0)
for ((drink, price) in prices) {
println("$drink costs $price")
}The loop variable (drink, i) is read-only and exists only inside the loop. For "just do this n times" without needing the number, repeat(3) { println("Brewing…") } is a tidy alternative.
The shortcut
Ask "What do I actually need each time round: the item, the position, or both?"
- Item only →
for (x in list). - Position only →
for (i in list.indices). - Both →
for ((i, x) in list.withIndex()). - Key and value →
for ((k, v) in map).
What do we need?
The drink name and its position, so both:
withIndex().
The off-by-one trap for (i in 0..drinks.size) reaches index 3 and crashes. until or indices avoids it.
Drills
Answer fast — trust the rule.
What does for (i in 1..4) print(i) print?
val d = listOf("a", "b", "c"). Which loop crashes with an index error?
Which loop gives both position and item?
How do you loop over a map's keys and values together?
Remember
forwalks through a range, collection or map; there is no counting form.- Pick the shape: item,
indices,withIndex(), or(k, v)for maps. 0..sizegoes one too far; useuntilorindices.
