Programming in Swift: Fundamentals

Oct 19 2021 · Swift 5.5, iOS 15, Xcode 13

Part 3: Control Flow

24. Nested Loops & Early Exit

Episode complete

Play next episode

Next
About this episode

Leave a rating/review

See forum comments
Cinema mode Mark complete Download course materials
Previous episode: 23. Challenge: Iterating Collections Next episode: 25. Challenge: Nested Loops & Early Exit

Get immediate access to this and 4,000+ other videos and books.

Take your career further with a Kodeco Personal Plan. With unlimited access to over 40+ books and 4,000+ professional videos in a single subscription, it's simply the best investment you can make in your development career.

Learn more Already a subscriber? Sign in.

Notes: 24. Nested Loops & Early Exit

Update Notes: The student materials have been reviewed and are updated as of October 2021.

Transcript: 24. Nested Loops & Early Exit

So far in this course, you’ve been working with loops that operate over full ranges; in other words, your loop always goes from start to finish with no interruption.

But what if you don’t want to finish the loop? What if you only want to loop until you’ve satisfied a particular condition, and then get on with the rest of your program?

It looks like you need a break! No, not that kind of break: a break statement.

The break statement lets you exit a loop early when you hit a particular condition, so you don’t have to waste time looping when it’s no longer necessary.

And you’ll find that you also will run into arrays that have an element or two you don’t want to deal with, or that you need to do some special processing on. You can use the continue statement to tell Swift “Hey, treat this element in a special way…and then continue looping over the rest of the array.”

And you’ve also only dealt with single loops - so far. But you can actually put a loop INSIDE another loop if you have some advanced processing needs. Sound strange? A little, but once you see it in action, you’ll see how nested loops can be useful in some scenarios.

Open up the playground page for this video, and get ready for a break! Er, you know what I mean.

Sometimes you’ll want to break out of a loop early. You can do that using the break statement, which immediately stops the execution of a loop and continues on to the code after the loop.

Let’s take the pool temperature example from the last exercise. And since I’m leaving on vacation and flying to Alaska on Thursday, I really only want to see the temperatures up to and including Wednesday.

So I create a for loop, for i in 0 to daysOfTheWeek.count:

for i in 0..<daysOfTheWeek.count {
    print("\(daysOfTheWeek[i]): \(poolTemperature[i])")
}

But I don’t want to print out anything once I hit Thursday. So I’ll add an if block there, to check if the current element of the daysOfTheWeek array has “Thursday”…

    if daysOfTheWeek[i] == "Thursday" {

    }

…and then I simply put the “break” instruction in there to tell Swift to exit the loop and move on, before it prints anything:

    if daysOfTheWeek[i] == "Thursday" {
        break
    }

Now you can see that the console only prints out the days from Sunday to Thursday.

Note that nothing else in this block of code executed: Swift immediately halts the execution of the code inside this block and carries on without printing anything out.

Let me quickly put a little marker in there, so you can tell the output from the different sections apart: print(”—”)

Sometimes you don’t want to break; instead, you want to do something special for a particular element in an array.

Let me construct a similar loop below; I’m just going to cut and paste this loop since the code is so similar:

for i in 0..<daysOfTheWeek.count {
    if daysOfTheWeek[i] == "Thursday" {
        break
    }
    print("\(daysOfTheWeek[i]): \(poolTemperature[i])")
}

If you’re a music fan, you might know the old song by The Cure named “Friday I’m in Love”. So I want to print out “I’m in love” instead of the temperature when we encounter the “Friday” element.

So change your if statement to this:

    if daysOfTheWeek[i] == "Friday" {

…and instead of “break”, print out “I’m in love”:

        print("I'm in love")

And then immediately after that, put the continue statement, to tell Swift to continue with the loop:

        continue

And the console shows that once Swift encountered the “Friday” element, it printed “I’m in love” and continue told Swift to stop executing the code, but carry on with the next iteration through the loop.

That’s the main difference between break and continue; break stops the loop entirely, while continue only stops the current iteration and then goes back to looping.

Let me add another quick divider before I move on:

print("---")

Now, nesting loops sounds a bit weird at first. Why would you want to have a loop inside a loop?

Let me give you the example of a ten-story hotel, and I’ve just added five new floors to it, floors eleven through fifteen. I can print out all of the new floors in the hotel, like so:

for floor in 11...15 {
    print(floor)
}

Now think about how a hotel is constructed: each floor has a set of rooms. My hotel has four rooms per floor: rooms 1, 2, 3 and 4. I want my room numbers to be the floor number and the room number together, so I can tell guests to go to room 11-4 or 15-1.

I need to print out all of the new room numbers for the new floors in the hotel, so let me delete that print statement and add another loop inside the existing loop to loop over the rooms:

for floor in 11...15 {
    for room in 1...4 {

    }
}

…and then I’ll put in a print statement there to print out the floor and the room together:

        print("\(floor)-\(room)")

So if you run your eye down the list, you can see how the loop runs through floor 11 first, then rooms 1 through four.

Then the inner loop ends, and you go back to the outer loop for the next floor, 12.

The inner loop then runs through rooms 1 to 4, and then it repeats again, all the way to 15.

You can also use the break and continue statements inside of nested loops!

Now I was all ready to put the room numbers on each door, but I just learned that we only ordered three beds for each new floor, so we’re going to have to ignore the first room on each floor because of a bed shortage. Yikes!

I can skip printing room number 1 with a simple if statement and a continue statement, just inside the room loop, where I check if room is equal to four:

        if room == 1 {
            continue
        }

Now you can see that the console only prints three rooms per floor, instead of four. The continue statement here only breaks the inner loop; it doesn’t affect the outer loop.

When you hit this break condition here, Swift says “OK, I’m going to stop executing this code, and move on”…where moving on means going to the next iteration of the outer floors loop.

So! Am I ready to open this hotel? No, not yet. I’ve just been informed that the thirteenth floor of the hotel is haunted. The hotel business is HARD, man!

OK, so I want to not print anything when I get to the thirteenth floor, but I DO want to go on and print room numbers for floors fourteen and fifteen.

That can be done with a continue statement in the outer loop, right here. We check to see if floor is equal to thirteen:

    if floor == 13 {

    }

And if this is true, then continue:

    if floor == 13 {
        continue
    }

And the console now prints out floors 11, 12, 14, and 15, and only rooms 2, 3 and 4 on each floor. There! I think we’re ready to open this hotel.

Oh, wait. Apparently the staff lost some of the pieces to assemble the bed in rooms 12-3 and 12-4, so we can’t open those rooms either. So basically once I hit room 12-3, I need to just get out of the inner loop and not print the rest of the rooms on floor 12.

Let me check for that condition with a Boolean operator: if floor is equal to 12 and room is equal to three, I want to continue.

        if floor == 12 && room == 3 {
            continue
        }

Oh, wait, that’s not quite right. It’s only continuing the inner loop, and printing room 12-4. I want to get out of this inner loop and continue the outer loop instead so it doesn’t print 12-4.

I can use labeled statements to tell Swift exactly where I want to continue execution. All I need to do is add a label to the beginning of each of my loop statements like so:

floor_loop: for floor in 11...15 {
    if floor == 13 {
        continue
    }
    room_loop: for room in 1...4 {

Now, I can say “continue floor_loop” here, to tell Swift to stop the inner loop, and continue with the labeled outer loop:

        if floor == 12 && room == 3 {
            continue floor_loop
        }

There. Finally! Time to kick off the grand opening of this hotel with some champagne! (pop!)

You’ve covered a lot in this video - good job, you!

If you’re not too pooped from loops, head on into the next video where I’ve got a few challenges for you to see if you really understand nested loops, break, continue, and labeled statements. See you there!