So far in this course, you’ve been working with loops that operate over lists; 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 list 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 Dart “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.
To get started, open a new instance of DartPad at dartpad.dev. We’re start by creating a list of days in the week.
var daysOfTheWeek = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
Now lets loop through the days of the week. This is old news. We’ve done it before.
for (var day in daysOfTheWeek) {
print(day);
}
Yet, we don’t want to print out anything for Thursday, so let’s add an if-statement before our print statement.
for (var day in daysOfTheWeek) {
if (day == 'Thursday') {
}
print(day);
}
Now lets add a break to tell Dart to exit the loop and move on before it prints out anything.
for (var day in daysOfTheWeek) {
if (day == 'Thursday') {
break;
}
print(day);
}
Notice that it only prints out Monday, Tuesday and Wednesday. After which, the for-loop reaches Thursday and then breaks.
This is nice but we don’t want the loop to end. Rather, we just want to skip Thursday but continue iterating throughout the list. For this, we change the break to a continue.
for (var day in daysOfTheWeek) {
if (day == 'Thursday') {
continue;
}
print(day);
}
Now run the program. This time, you’ll see all the days of the week except Thursday.
There are times when you’ll want to incorporate loops inside of loops. This is actually a very common occurrence. This is called nesting. For example, you may have a list of students so you’ll loop through that list. In that loop, you then may loop through that person’s grades.
This is where break statement really comes into play. When you break out of a nested loop, the control flow returns to the parent loop.
We can actually control where we break or continue by way of a label. A label is the name of a jump point. You give it a name followed by a colon. After which, in your loop, you can jump to it by way of the continue or break statement. Labels can be a useful tool but make sure to go easy with them. If you find your control flow jumping all over the place, then you may be adding unnecessary complexity to your program and you should rethink your approach.
Okay, let’s get busy with creating a nested. We’ll start with a loop of people involved in a movie production. I’ll leave it to you to guess the movie.
var movieOne = ['Peter Jackson', 'Ian Mckellen', 'Viggo Mortensen'];
var movieTwo = ['Jackie Chan', 'Alan Smithee', 'Sylvester Stallone'];
var movieThree = ['Chris Pratt', 'Kurt Russell', 'Sean Gunn'];
Now let’s take these three lists, and put them in another list.
var movies = [movieOne, movieTwo, movieThree];
Let’s also create a variable to store all the credits that we process and the total movies that we process.
var totalCredits = 0;
var processedMovies = 0;
At this point, we have a list that contains three lists. Lets process this. We’ll print out each credit as we process it then print out the results.
for (var movie in movies) {
for (var credit in movie) {
print(credit);
totalCredits += 1;
}
processedMovies += 1;
}
print('---');
print('total processed movies: $processedMovies');
print('total processed credits: $totalCredits');
Now run the program. Here we see the list of processed credits, followed by the completed stats. Except there’s a problem. We don’t want to process movies that have Alan Smithee in them. Alan Smithee is a pseudonym for directors who take their names of their project. If we run into an Alan Smithee film, we’ll skip to the next movie. First, let’s write some logic to rollback the processing.
var processedCredit = 0;
for (var movie in movies) {
processedCredit = 0;
for (var credit in movie) {
print(credit);
processedCredit += 1;
}
totalCredits += processedCredit;
processedMovies += 1;
}
Here we create a processed credit variable. We reset it for each movie. Once we loop through all the credits, we add the processed credit and increase the processed movies. Now lets add our Alan Smithee check:
if (credit == 'Alan Smithee') {
break;
}
Now run the program. You can see it still processed three movies as well as seven credits. That’s because when we broke out of the loop, we continued to process the results. Instead, let’s create a label for the outer loop.
outerloop:
for (var movie in movies) {
Now let’s continue to the outer loop. This allows for the loop to continue its iteration.
if (credit == 'Alan Smithee') {
continue outerloop;
}
Now run the program. You’ll see we have processed two movies and six credits. The movie with Alan Smithee in it was skipped.
If you were confused by the jumping around now imagine if we used lots of labels. Again, use them sparingly but always keep the break and continue keywords in your tool belt.