Kotlin Loops and Ranges

Repeat work with for, while, do-while and repeat, and describe sequences of numbers with ranges like 1..10, until, downTo and step.

Lesson 7 of 43Beginner18 min read

Computers are brilliant at doing the same thing many times without getting bored. Printing a times table, adding up a list of prices, checking every email in a mailing list or retrying a download until it succeeds are all jobs for a loop.

Kotlin's main loop is for, and it works hand in hand with ranges: compact descriptions of sequences of numbers, like 1..10 for one to ten. Ranges can count up or down, skip numbers with step, and stop before the end with until. There are also while loops for repeating until a condition changes, and a tidy repeat(n) for doing something a fixed number of times.

In this lesson you'll loop over ranges and lists, count down and in steps, use while and do-while, and control loops with break and continue.

for loops and ranges

Kotlin
for (i in 1..5) {
    println(i)          // 1, 2, 3, 4, 5
}
  • 1..5 is a range that includes both ends.
  • for (x in something) visits each item, giving it the name x.
  • The loop variable is created fresh each time; you don't declare or increase it yourself.
RangeValues
1..51, 2, 3, 4, 5
1 until 5 or 1..<51, 2, 3, 4
5 downTo 15, 4, 3, 2, 1
0..10 step 20, 2, 4, 6, 8, 10
'a'..'e'a, b, c, d, e

Looping over collections

for works with any collection, not just numbers:

Kotlin
val fruits = listOf("apple", "pear", "plum")
for (fruit in fruits) println(fruit)
for (i in fruits.indices) println("$i: ${fruits[i]}")
for ((i, fruit) in fruits.withIndex()) println("${i + 1}. $fruit")

indices is the range of valid positions, 0 until size. withIndex() gives the position and the item together, unpacked into two names with brackets. This is safer than counting positions by hand, which risks going one past the end.

while, do-while and repeat

A while loop repeats as long as its condition is true, which suits situations where you don't know in advance how many times it will run:

Kotlin
var balance = 100.0
var years = 0
while (balance < 200) {
    balance *= 1.05
    years++
}

do { } while (condition) always runs its body at least once before checking. repeat(3) { println("Hip hip, hooray!") } runs a block a fixed number of times, with the count available as it, starting at 0.

break, continue and labels

  • break stops the loop immediately.
  • continue skips the rest of this pass and moves on to the next item.

In nested loops, break only leaves the innermost loop. To leave an outer loop, give it a label with name@ and use break@name:

Kotlin
outer@ for (row in 1..3) {
    for (col in 1..3) {
        if (row * col == 4) break@outer
        print("${row * col} ")
    }
}

Ranges are values you can store and test

A range isn't only something to loop over. It's an ordinary value, so you can keep it in a variable, pass it to a function and ask it questions:

Kotlin
val teen = 13..19
println(15 in teen)        // true
println(20 !in teen)       // true
println(teen.first)        // 13
println(teen.last)         // 19
println(teen.count())      // 7
println(teen.sum())        // 112

in checks membership without looping, so age in 13..19 is a tidy replacement for age >= 13 && age <= 19. Ranges of Double work for this kind of check too, as in 0.5 in 0.0..1.0, but you can't loop over them, because there's no obvious "next" decimal number.

When you add step, the last value is the last one the steps actually reach, not necessarily the end you wrote. (1..10 step 4).toList() is [1, 5, 9], so its last is 9. A range written backwards, such as 5..1, is simply empty: (5..1).isEmpty() is true, which is why the loop over it never runs. Use reversed() or downTo when you want to go the other way.

A for loop works over anything that can hand out its items one at a time. That includes strings, which give you each Char, and maps, which give you entries you can unpack into a key and a value:

Kotlin
for (ch in "abc") print(ch.uppercaseChar())     // ABC
for ((name, age) in mapOf("Ana" to 30, "Ben" to 25)) {
    println("$name is $age")
}

Finally, the loop variable is read-only. Writing i = 5 inside for (i in 1..3) is a compile error, because each pass gets a fresh val. If you need a counter you can change, use a while loop with a var.

Kotlin Loops Syntax

Loops

for (i in 1..10) { }
for (i in 0 until n) { }         // or 0..<n
for (i in 10 downTo 0 step 2) { }
for (item in list) { }
for ((i, item) in list.withIndex()) { }
while (cond) { }
do { } while (cond)
repeat(3) { println(it) }
outer@ for (...) { break@outer }

Kotlin Loops Summary

  • for (x in range) loops over each value; 1..5 includes both ends.
  • until (or ..<) excludes the end, downTo counts down and step skips values.
  • Loop over lists directly, with indices, or with withIndex() for position and item.
  • while checks first; do-while runs at least once; repeat(n) runs a block n times.
  • break ends a loop, continue skips to the next pass, and labels control outer loops.

Kotlin Loops Examples

Each example shows the code, the output it produces and what each part does.

Example 1

A times table and a countdown

Kotlin
fun main() {
    val n = 7
    for (i in 1..5) {
        println("$n x $i = ${n * i}")
    }
    for (s in 10 downTo 0 step 5) {
        print("$s ")
    }
    println("Liftoff!")
}
Output
7 x 1 = 7
7 x 2 = 14
7 x 3 = 21
7 x 4 = 28
7 x 5 = 35
10 5 0 Liftoff!
Line-by-line explanation
  1. Line 31..5 includes both 1 and 5.
  2. Line 6downTo counts down, and step 5 jumps by five each time.
  3. Line 9println finishes the countdown line.
Example 2

Totals with a list and withIndex

Kotlin
fun main() {
    val prices = listOf(2.50, 4.00, 1.25)
    var total = 0.0
    for ((i, price) in prices.withIndex()) {
        println("Item ${i + 1}: £$price")
        total += price
    }
    println("Total: £$total")

    for (i in 0 until prices.size) {
        if (prices[i] < 2.0) println("Item ${i + 1} is cheap")
    }
}
Output
Item 1: £2.5
Item 2: £4.0
Item 3: £1.25
Total: £7.75
Item 3 is cheap
Line-by-line explanation
  1. Line 4withIndex gives the position and the value together.
  2. Line 5Doubles print without trailing zeros, as 2.5, not 2.50; use "%.2f".format for money.
  3. Line 10until stops before prices.size, so the index never goes out of range.
Example 3

while, repeat, break and continue

Kotlin
fun main() {
    var savings = 1000.0
    var years = 0
    while (savings < 1500) {
        savings *= 1.1
        years++
    }
    println("Years to reach 1500: $years")

    repeat(3) { println("Attempt ${it + 1}") }

    for (n in 1..10) {
        if (n % 2 == 0) continue
        if (n > 7) break
        print("$n ")
    }
    println()
}
Output
Years to reach 1500: 5
Attempt 1
Attempt 2
Attempt 3
1 3 5 7 
Line-by-line explanation
  1. Lines 4 to 7Grow by 10% a year until savings reach 1500: 1100, 1210, 1331, 1464.1 and then 1610.51, after 5 years.
  2. Line 10repeat runs the block three times; it counts from 0.
  3. Line 13continue skips even numbers.
  4. Line 14break stops the loop as soon as n passes 7.

Common Kotlin Loops Mistakes

Expecting until to include the end

Don't
for (i in 1 until 5) print(i)     // 1234, not 12345
Do
for (i in 1..5) print(i)          // 12345

Counting down with ..

Don't
for (i in 5..1) print(i)          // prints nothing: the range is empty
Do
for (i in 5 downTo 1) print(i)    // 54321

A while loop that never ends

Don't
var tries = 0
while (tries < 3) {
    println("Trying")             // tries never changes
}
Do
var tries = 0
while (tries < 3) {
    println("Trying")
    tries++
}

Kotlin Loops in Real Projects

Loops in apps

Apps loop over lists of messages to display them, over shopping cart items to total the price, and over files to process them. Games run a loop for every frame. In real Kotlin code you'll often use collection functions like forEach, map and filter, covered in the collection operations lesson, which replace many hand-written loops with a single line.

Kotlin Loops FAQ

How do I loop with an index in Kotlin?

Use for ((i, item) in list.withIndex()) to get the position and the item together, or for (i in list.indices) if you only need positions. Both avoid writing 0 until list.size by hand, and indices is automatically empty for an empty list.

What is the difference between until and .. in Kotlin?

1..5 includes both ends, giving 1 to 5. 1 until 5, also written 1..<5, stops before the end, giving 1 to 4. The exclusive form is the natural choice when looping over positions, because the last valid index is always one less than the size.

Can I remove items from a list while looping over it?

Not with a plain for loop over a MutableList: changing the list while you're iterating over it usually throws a ConcurrentModificationException. Use list.removeAll { it % 2 == 0 } to remove matching items in one go, or build a new list with filter.

How do I skip to the next item in a forEach?

continue and break only work in real loops such as for and while. Inside forEach { }, return@forEach ends the current item's lambda and moves on to the next one, which acts like continue. If you need break, switch to a for loop.

How do I check if a number is between two values in Kotlin?

Use a range with in: if (score in 0..100) is true for 0, 100 and everything between. For an upper bound that should be excluded, write score in 0..<100. To force a value into a range instead of checking it, use coerceIn: 150.coerceIn(0, 100) is 100.

Kotlin Loops Exercises

Answer each one and check it instantly. If you get stuck, open the hint before the answer.

Fill in the blankseasy

Complete the loop so it prints 10, 9, 8 ... 1.

for (i in 10  1) println(i)
Predict the outputeasy

How many numbers does for (i in 0 until 4) loop over?

Predict the outputmedium

What does this print?

for (i in 1..10 step 3) print("$i ")
Multiple choicemedium

Which loop always runs its body at least once?

Predict the outputhard

What does this print?

var total = 0
for (n in 1..6) {
    if (n == 4) continue
    total += n
}
println(total)

Kotlin Loops Quiz

5 questions to check what you learned.

  1. Does the range 1..3 include 3?

    • No
    • Yes
    • Only in while loops
    • Only with step
  2. What does repeat(4) { } do?

    • Runs the block four times, with it from 0 to 3
    • Repeats the program four times
    • Creates a list of four items
    • Waits four seconds
  3. What does continue do inside a loop?

    • Skips the rest of this pass and starts the next one
    • Ends the loop
    • Restarts from the first item
    • Pauses the program
  4. How do you leave an outer loop from inside an inner loop?

    • break twice
    • Label the outer loop, such as outer@, and use break@outer
    • return@inner
    • It isn't possible
  5. What does for (i in 5..1) do?

    • Counts down from 5 to 1
    • Throws an exception
    • Nothing: the range is empty
    • Counts up from 1 to 5