Start learning free

LESSON 151 OF 348 · LOOPING OVER ARRAY INDICES

Break in For Loops in Kotlin

Lesson Read the full explanation

With the break statement, we can prematurely terminate a loop from inside that loop.

When Kotlin reaches the break statement, it's going to immediately terminate the loop without checking any conditions.


Breaking a for loop:

In this example, we will terminate the loop when we find a "banana" in our array:

val fruits = arrayOf("kivi", "orange", "banana", "apple", "pear")
for (fruit in fruits) {
	println(fruit)
	if (fruit == "banana") {
		break
	}
}

The output of this code is:

kivi
orange
banana

As you can see, our program doesn't print apple and pear.

Here's what happens during this loop:

1. First iteration:
	a. fruit = "kivi"
	b. println(fruit) => Output: kivi
	c. Is fruit == "banana"? No.
	
2. Second iteration:
	a. fruit = "orange"
	b. println(fruit) => Output: orange
	c. Is fruit == "banana"? No.
	
3. Third iteration:
	a. fruit = "banana"
	b. println(fruit) => Output: banana
	c. Is fruit == "banana"? Yes:
          break => Exit the loop immediately

Here's the same program but iterating through the array with indices instead:

val fruits = arrayOf("kivi", "orange", "banana", "apple", "pear")
for (i in fruits.indices) {
	println("Index " + i + ": " + fruits[i])
	if (fruits[i] == "banana") {
		break
	}
}

The output of this code is:

Index 0: kivi
Index 1: orange
Index 2: banana

As you can see, our program doesn't print apple and pear.


Assignment
Let's print all the lessons our student finished!


Hint
Look at the examples above if you get stuck.


STEP 1 OF 3
    Ctrl + Enter to check

    KOTLIN · LOOPING OVER ARRAY INDICES

    Break In For Loops in Kotlin, explained

    What break does

    A for loop normally visits every element. The break statement ends the loop early: as soon as Kotlin reaches it, the loop stops, no condition is checked again, and the program continues with the first statement after the loop.

    Here, the loop stops when it finds a banana:

    val fruits = arrayOf("kivi", "orange", "banana", "apple", "pear")
    for (fruit in fruits) {
        println(fruit)
        if (fruit == "banana") {
            break
        }
    }
    
    kivi
    orange
    banana
    

    "apple" and "pear" are never visited. Each iteration does the same three things: assign the next element to fruit, print it, and test it. The first two iterations find that the test is false and carry on. In the third, the test is true, so break runs and the loop is over.

    The same loop with indices

    Break works the same way when the loop runs over indices. Using fruits.indices gives the position as well as the element:

    for (i in fruits.indices) {
        println("Index $i: ${fruits[i]}")
        if (fruits[i] == "banana") {
            break
        }
    }
    
    Index 0: kivi
    Index 1: orange
    Index 2: banana
    

    This is the form to use when you need the position of the match, for example to report where the banana was. The string template "Index $i: ${fruits[i]}" inserts values into the text; $i works for a simple name, and braces are needed for an expression like fruits[i].

    Where the break goes matters

    The lesson's loop prints first and checks second, so the matching element is included in the output. Swapping the two statements changes the result:

    for (fruit in fruits) {
        if (fruit == "banana") {
            break
        }
        println(fruit)
    }
    
    kivi
    orange
    

    Now the check happens before the print, so the banana is not printed. Decide whether the element that triggers the stop should be processed, and put break after or before that processing to match.

    Break and nested loops

    A plain break leaves only the innermost loop it is written in. With a loop inside a loop, the outer loop carries on:

    val grid = arrayOf(intArrayOf(1, 2), intArrayOf(3, 4))
    for (row in grid) {
        for (v in row) {
            if (v == 2) break
            println(v)
        }
    }
    
    1
    3
    4
    

    When the inner loop reaches 2 it stops, but the outer loop moves on to the next row. To leave both loops, Kotlin lets you name the outer loop with a label and break to it:

    outer@ for (row in grid) {
        for (v in row) {
            if (v == 2) break@outer
            println(v)
        }
    }
    

    This prints only 1. Labels are rarely needed; reach for one only when a nested loop must stop completely.

    The exercise

    The starting code has an array of lessons and the last one the student finished:

    val lessons = arrayOf("variables", "conditionals", "arrays", "functions", "loops")
    val lastFinishedLesson = "functions"
    

    The task is to print every lesson up to and including the last finished one, and nothing after it. The steps:

    1. Loop over the array. for (lesson in lessons) hands out each lesson in order. No index is needed, because only the values matter.
    2. Print the lesson. Print "Finished " joined with lesson using +.
    3. Stop after the last finished one. Compare lesson with lastFinishedLesson, and when they are equal, break. Because the comparison comes after the print, the last finished lesson is printed before the loop ends.
    val lessons = arrayOf("variables", "conditionals", "arrays", "functions", "loops")
    val lastFinishedLesson = "functions"
    
    for (lesson in lessons) {
        println("Finished " + lesson)
        if (lesson == lastFinishedLesson) {
            break
        }
    }
    

    The output is:

    Finished variables
    Finished conditionals
    Finished arrays
    Finished functions
    

    "loops" is never reached. In Kotlin, == on strings compares their contents, so lesson == lastFinishedLesson is true exactly when the two texts are equal. If no lesson matched, the loop would simply run to the end and print all five.

    When to use break, and common mistakes

    Break fits searches: once the loop has found what it was looking for, visiting the rest of the array is wasted work. In the worst case, when nothing matches, the loop still runs to the end, so break saves time on average but doesn't change the worst case.

    • Break outside a loop. break is only valid inside a loop. Anywhere else the compiler reports an error.
    • Expecting break to leave the function. It only leaves the loop. Statements after the loop still run. To end the whole function, use return.
    • Printing before or after the check by accident. If the output has one line too many or too few at the end, check the order of the print and the if.
    • Forgetting the braces. The if and its break must both sit inside the loop's braces. A break that falls outside the loop body is an error.

    Key takeaways

    • break ends the loop immediately; the code after the loop runs next.
    • Whether the triggering element is processed depends on whether the work comes before or after the break check.
    • A plain break affects only the innermost loop; use a label such as break@outer to leave an outer one.
    Keep going with KotlinAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free