0 1 00:00:00,510 --> 00:00:00,900 All right. 1 2 00:00:00,930 --> 00:00:10,560 So welcome to the Swift Deep Dive on loops. And loops are really important constructs in programming 2 3 00:00:10,590 --> 00:00:13,030 in general, not just in Swift. 3 4 00:00:13,050 --> 00:00:21,390 So let's say that we have a scenario where you want a robot to, say, drop a coin on every single tile 4 5 00:00:21,810 --> 00:00:27,240 and you want him to repeat this process so that he covers all of the tiles on the floor. 5 6 00:00:27,240 --> 00:00:33,600 Now, you could write your code pretty much like this where you just tell it to move(1) putCoin, move 6 7 00:00:33,600 --> 00:00:34,680 (1) putCoin. 7 8 00:00:34,680 --> 00:00:39,500 But notice how many parts of our code is being repeated. 8 9 00:00:39,660 --> 00:00:45,810 And while you could probably simplify this by putting move and put coin into its own function as we 9 10 00:00:45,810 --> 00:00:52,230 learned previously, and then calling that function, but it's still quite repetitive. And what are we? 10 11 00:00:52,230 --> 00:00:53,610 We're programmers, right? 11 12 00:00:53,820 --> 00:00:55,200 And what does Bill Gates say? 12 13 00:00:55,350 --> 00:01:00,840 Well, you will always choose a lazy person to do a difficult job because it will find an easy way to 13 14 00:01:00,840 --> 00:01:01,790 do it. 14 15 00:01:01,830 --> 00:01:03,530 So how can we be lazy? 15 16 00:01:03,540 --> 00:01:10,200 How can we use programming and the computer to do all of these repetitive tasks instead of us having 16 17 00:01:10,200 --> 00:01:11,730 to type it all out? 17 18 00:01:11,730 --> 00:01:18,630 Well, this is where loops really come in handy. And the most common type of loop that you'll see is the 18 19 00:01:18,630 --> 00:01:19,810 For In Loop. 19 20 00:01:19,860 --> 00:01:23,060 So let's say that you've got an array of some names. 20 21 00:01:23,100 --> 00:01:28,560 Say, these are the name of your contacts with your friends and you want to be able to print out each 21 22 00:01:28,560 --> 00:01:32,140 of them in order. Because this is an array, 22 23 00:01:32,160 --> 00:01:34,670 so an ordered sequence of elements, 23 24 00:01:34,680 --> 00:01:41,880 we can simply write "for," and we create this entirely new constant in here. 24 25 00:01:41,880 --> 00:01:50,400 So this name is a new constant that we've decided to call name, and then the "in" keyword is followed by 25 26 00:01:50,400 --> 00:01:51,750 the actual sequence. 26 27 00:01:51,750 --> 00:01:54,630 So in this case, it's our array up here. 27 28 00:01:54,630 --> 00:02:02,850 So now when we go ahead and print each of the names with a "Hello," then what's going to happen is this 28 29 00:02:02,850 --> 00:02:08,000 loop is going to run for as many times as there are elements in our array. 29 30 00:02:08,010 --> 00:02:10,370 So in this case, it's one, two, three, four. 30 31 00:02:10,890 --> 00:02:14,210 And once this code gets executed, 31 32 00:02:14,520 --> 00:02:16,740 we'll see, "Hello, Anna!" and then, "Hello, Alex!" 32 33 00:02:16,740 --> 00:02:18,500 "Hello, Brian! and "Hello, Jack!" 33 34 00:02:18,930 --> 00:02:26,220 So it's looping through our array and it's performing some sort of action. In this case, just simply printing 34 35 00:02:26,220 --> 00:02:28,230 out the name and the word "Hello," 35 36 00:02:28,530 --> 00:02:32,670 and it's doing this many, many times without us having to explicitly write 36 37 00:02:32,970 --> 00:02:33,650 Hello, 37 38 00:02:33,660 --> 00:02:42,940 name, square brackets, zero. Hello, name, square bracket 1, et cetera. So we can do this as long as we have a sequence 38 39 00:02:42,940 --> 00:02:43,660 to work with. 39 40 00:02:44,200 --> 00:02:47,800 Another way is working with a range, 40 41 00:02:47,830 --> 00:02:48,220 right? 41 42 00:02:48,220 --> 00:02:54,080 So we've seen the range operator and this, as you might remember, is a close-range operator. 42 43 00:02:54,070 --> 00:02:59,890 So this is a range between 1 and 5 including both 1 and 5. 43 44 00:02:59,890 --> 00:03:06,430 So in this case, we've created again another constant which is called number and this number is going 44 45 00:03:06,430 --> 00:03:12,810 to be set to equal each value in this sequence for every time this loop gets run. 45 46 00:03:12,820 --> 00:03:19,630 So if we decided to print out the number each time the loop is run, then what's going to happen is that 46 47 00:03:19,630 --> 00:03:26,650 this number constant is first going to be equal to 1, the first time the loop runs, and then this entire 47 48 00:03:26,650 --> 00:03:28,110 block gets executed, 48 49 00:03:28,210 --> 00:03:34,570 and we should get the words "Hello 1" printed. And then the next time number runs, 49 50 00:03:34,660 --> 00:03:37,180 it's now equal to the next value in the range, 50 51 00:03:37,180 --> 00:03:39,790 so it'll be 2, and so on and so forth. 51 52 00:03:39,790 --> 00:03:48,580 So we'll get this looping effect running a total of five times because our range goes from 1 all the 52 53 00:03:48,580 --> 00:03:51,180 way up to and including 5. 53 54 00:03:51,220 --> 00:03:58,390 Now, if you didn't actually need to use the value of the numbers in the range, then you can simply bypass 54 55 00:03:58,390 --> 00:04:05,230 it by adding just a underscore. So we could turn our code to look something like this. Because we don't 55 56 00:04:05,230 --> 00:04:06,930 need that number anymore, 56 57 00:04:06,940 --> 00:04:12,910 we just wanted, say, for example, the word "Hello" printed out five times, then we could change our for loop 57 58 00:04:12,910 --> 00:04:14,170 to look something like this. 58 59 00:04:15,070 --> 00:04:20,430 And now it's going to do what we asked to print the words "Hello" from 1 to 5, 59 60 00:04:20,460 --> 00:04:28,180 so a total of five times. And we're basically just getting on loop to run for a specified number of times 60 61 00:04:28,480 --> 00:04:38,160 without using any of the values inside this sequence that we've provided here. Coming back to our original 61 62 00:04:38,160 --> 00:04:44,880 example where we had our little robot to simplify things. Let's say that we only wanted to put it along 62 63 00:04:44,880 --> 00:04:51,390 this one horizontal line, right, where it's very much "move (1) putCoin, move (1) putCoin. And this is 63 64 00:04:51,390 --> 00:04:58,290 the code that we would have had to write if we weren't using loops. But by simply using a loop, we can 64 65 00:04:58,290 --> 00:05:06,450 get putCoin, move (1) to be repeated five times. And, again, in this case, we're not using any of the values 65 66 00:05:06,450 --> 00:05:07,900 in our sequence here, 66 67 00:05:07,920 --> 00:05:12,140 so we've put an underscore here, instead of a name for a constant. 67 68 00:05:12,690 --> 00:05:18,660 So, now let's take a look at this in our playgrounds and see it in action. 68 69 00:05:18,690 --> 00:05:21,880 Here I've got five types of sequences. 69 70 00:05:21,960 --> 00:05:30,870 I've got an array of fruits. I've got a dictionary of contacts and their phone numbers. 70 71 00:05:30,990 --> 00:05:39,180 I've got a string. I've got a halfOpenRange which has that less than symbol at the end. And also 71 72 00:05:39,180 --> 00:05:43,020 a closRange, which you saw earlier, which just has the three dots. 72 73 00:05:43,020 --> 00:05:45,460 So, now I can create a for loop. 73 74 00:05:45,570 --> 00:05:51,960 So as soon as I starts writing "for," you can see that Xcode gives me that code snippet of a "for" statement 74 75 00:05:52,560 --> 00:05:57,430 and you can see that we have three parts which we need to fill and the rest are keywords, the "for" and the "in." 75 76 00:05:57,470 --> 00:06:03,600 So, for item in items. The easiest one is, of course, fruit, right? 76 77 00:06:03,600 --> 00:06:06,950 This is the singular of the fruits plural. 77 78 00:06:07,050 --> 00:06:13,770 This is the name that I'm giving a constant which is going to be assigned to each element inside my 78 79 00:06:13,770 --> 00:06:15,270 fruits array. 79 80 00:06:15,270 --> 00:06:18,680 So my fruit array goes after the key word. 80 81 00:06:18,720 --> 00:06:25,040 And now as for my code, I'm just going to simply print out each fruit. 81 82 00:06:25,260 --> 00:06:28,230 So notice how this is an array of strings, 82 83 00:06:28,350 --> 00:06:34,080 but this is simply just a string. For every single time this for loop runs, 83 84 00:06:34,170 --> 00:06:39,890 this constant fruit will get assigned a value depending on where we are in this sequence. 84 85 00:06:39,900 --> 00:06:45,640 So, now if I run this code, you'll see that it prints out each of the items in order. 85 86 00:06:45,690 --> 00:06:48,000 Now, this is how arrays work. 86 87 00:06:48,000 --> 00:06:57,300 They are ordered sequences. But a close relative of the array is something called a Set. And a set is 87 88 00:06:57,300 --> 00:07:04,170 simply a more efficient type of collection that allows you to put in many, many items, such as what we've 88 89 00:07:04,170 --> 00:07:05,060 got here, 89 90 00:07:05,220 --> 00:07:08,890 but it does not guarantee the order of those items. 90 91 00:07:08,970 --> 00:07:15,390 So that means that if I now try and print fruit in fruits, you'll see that I won't get the original order 91 92 00:07:15,390 --> 00:07:21,360 that I put it in like I did with the array where I'm guaranteed that it's going to execute it in the 92 93 00:07:21,360 --> 00:07:25,820 order that I created the array. Once it turns into a set, 93 94 00:07:25,860 --> 00:07:31,680 it's just going to do it in the most efficient way possible and it's going to print down all the items 94 95 00:07:31,680 --> 00:07:33,890 in there, and it's going to loop through all of them 95 96 00:07:34,080 --> 00:07:37,380 but it's not guaranteeing any sort of particular order. 96 97 00:07:38,400 --> 00:07:44,970 So in certain cases, you might value the efficiency more than the order, in which case you would use a 97 98 00:07:44,970 --> 00:07:46,530 set data type, 98 99 00:07:46,530 --> 00:07:52,890 and other times, you really care about the order of the elements that went into that sequence, in which 99 100 00:07:52,890 --> 00:07:55,970 case you would use an array instead. 100 101 00:07:56,220 --> 00:07:59,180 The next thing is we've got a dictionary here, 101 102 00:07:59,190 --> 00:07:59,480 right? 102 103 00:07:59,550 --> 00:08:01,340 And we can do exactly the same thing. 103 104 00:08:01,350 --> 00:08:10,580 We can say, for person in our contacts, we're going to print the person's key. 104 105 00:08:10,680 --> 00:08:15,400 So notice how dictionaries are composed of key value pairs, right? 105 106 00:08:15,450 --> 00:08:20,010 Each item that goes in there has a key and a value. 106 107 00:08:20,040 --> 00:08:26,970 So if we loop through our contacts and every time this loop runs, we turn each of these items into a 107 108 00:08:26,970 --> 00:08:33,930 constant code person, and then we print person.key, we're going to get basically all of the names 108 109 00:08:34,080 --> 00:08:40,680 that's in our dictionary. And if we print person.value instead, we're going to instead get all of the 109 110 00:08:40,680 --> 00:08:45,040 values that are inside our contacts. 110 111 00:08:45,300 --> 00:08:51,110 Now, as you saw earlier in the previous lesson, we can do the same with string. 111 112 00:08:51,210 --> 00:08:58,800 So if we loop through each letter in our word "supercalifragilisticexpialidocious" and we print 112 113 00:08:58,920 --> 00:09:06,120 each of these letters, and go ahead and run our code, then you'll see that it actually takes each and 113 114 00:09:06,120 --> 00:09:11,310 every single letter of that string and print it out individually. 114 115 00:09:11,310 --> 00:09:19,050 So in total, our loop actually run a total of 34 times because there's 34 characters in this gigantic 115 116 00:09:19,050 --> 00:09:20,270 word. 116 117 00:09:20,460 --> 00:09:30,600 Now, as you saw in the slides earlier, we can use again the "for number in," say, our halfOpenRange and 117 118 00:09:30,870 --> 00:09:32,370 print the number, 118 119 00:09:33,000 --> 00:09:40,770 so now if we hit run, you'll see that it prints 1, 2, 3, 4, up to, but not including 5, because 119 120 00:09:40,770 --> 00:09:45,120 of this, the less than symbol, which turns it into a halfOpenRange. 120 121 00:09:45,120 --> 00:09:50,970 But instead if we use the closedRange operator which is just the three dots, then you'll see it prints 121 122 00:09:51,030 --> 00:09:54,160 1,2, 3, 4, including 5. 122 123 00:09:54,390 --> 00:09:57,610 So it runs the loop a total of five times in this case. 123 124 00:09:57,780 --> 00:10:01,550 And in this case, it runs it a total of four times. 124 125 00:10:01,650 --> 00:10:09,000 So if we wanted to simply just get it to run a particular block of code a number of times, then we can 125 126 00:10:09,000 --> 00:10:16,080 replace this constant with an underscore, which is the same as kind of saying like let, underscore, equal, 126 127 00:10:17,670 --> 00:10:18,010 I don't know, 127 128 00:10:18,030 --> 00:10:21,220 1 to 5, 128 129 00:10:21,330 --> 00:10:21,600 right? 129 130 00:10:21,600 --> 00:10:23,700 This is basically exactly the same thing. 130 131 00:10:23,700 --> 00:10:29,170 It just means that we're not gonna be using this constant anywhere within our code. 131 132 00:10:29,220 --> 00:10:35,160 So, now we can't print no because it doesn't exist anymore, but we can print something else. We can print 132 133 00:10:35,430 --> 00:10:44,370 "Loop is running." And now when I hit run, you'll see that in the halfOpenRange, it runs four times. 133 134 00:10:44,460 --> 00:10:52,240 So my block of code inside here is going to run four times as well. Now, another related type of loop 134 135 00:10:52,390 --> 00:11:00,520 is something called a While Loop. And while loops work where you have a "while" keyword, and then you have 135 136 00:11:00,580 --> 00:11:03,760 something that is tested, a condition, right? 136 137 00:11:03,820 --> 00:11:11,350 And if this condition say, I don't know," 8 is greater than five, or the sky is equal to blue, 137 138 00:11:11,350 --> 00:11:21,560 if that is true, then this entire loop is going to continuously run until this condition becomes false. 138 139 00:11:21,730 --> 00:11:29,140 As you can imagine, this can be dangerous if you expected something to turn false at some point, but it 139 140 00:11:29,140 --> 00:11:36,250 actually never does. Say, you expected, I don't know, the user to type a particular letter, "A," but they never 140 141 00:11:36,250 --> 00:11:37,470 type the letter "A," 141 142 00:11:37,540 --> 00:11:44,080 well, then in that case, your while loop is going to run until forever which is called an infinite loop. 142 143 00:11:44,950 --> 00:11:53,290 And if you search for one infinite loop in maps, what you'll discover is actually Apple's headquarters. 143 144 00:11:53,330 --> 00:12:00,520 So right here. This is how we programmers try to be funny by building large buildings representing concepts 144 145 00:12:00,580 --> 00:12:01,950 in programming. 145 146 00:12:02,350 --> 00:12:07,870 Going back to our playground, let's say that I wanted to create a while loop instead, 146 147 00:12:07,870 --> 00:12:08,690 right? 147 148 00:12:08,740 --> 00:12:14,670 So I start out with the "while" keyword and, again, Swift has a code snippet for that as well. 148 149 00:12:15,180 --> 00:12:22,060 And then, I'll have to supply a condition, in this case what I'm going to test is I want my while loop 149 150 00:12:22,060 --> 00:12:31,720 to run for a single second, so I can get hold of the current time right now by creating a variable code "now" 150 151 00:12:31,720 --> 00:12:44,440 by setting equal to Date.timeIntervalSince1970, and it's not going to recognize a date because 151 152 00:12:44,470 --> 00:12:54,220 I need to import the Foundation module in order to tell it about this Date object which is a single point 152 153 00:12:54,220 --> 00:13:03,940 in time. And the timeIntervalSince1970 is going to give me the number of seconds since 0 o' clock on 153 154 00:13:04,000 --> 00:13:07,300 January 1,1970. 154 155 00:13:07,300 --> 00:13:10,330 So this is a standard in Unix time. 155 156 00:13:10,330 --> 00:13:17,440 And what this means is that this now is going to be equal to the number of seconds since January 1, 156 157 00:13:17,460 --> 00:13:19,340 1971. 157 158 00:13:19,390 --> 00:13:26,380 I'm gonna create a constant code oneSecondFromNow and this is simply just going to equal to 158 159 00:13:26,770 --> 00:13:28,660 now + 1 second. 159 160 00:13:28,660 --> 00:13:36,300 Now, remember, this "now" is actually going to be equal to the value of the time when I run this code 160 161 00:13:36,310 --> 00:13:42,780 when line 13 gets executed. And then immediately, I'm going to add one second to it and I'm going 161 162 00:13:42,780 --> 00:13:51,910 to have a value of the number of seconds since 1970, January 1st, plus one second. And in my while condition, 162 163 00:13:51,970 --> 00:13:59,320 what I'm going to test is I'm going to say if now happens to be less than oneSecondFromNow, 163 164 00:13:59,350 --> 00:14:03,050 so as in one second has yet to pass, 164 165 00:14:03,100 --> 00:14:05,000 this is what that condition tests, 165 166 00:14:05,110 --> 00:14:09,670 well then I'm gonna go ahead and print "waiting..." 166 167 00:14:09,670 --> 00:14:13,590 There's one last thing that I have to do which is inside my while loop, 167 168 00:14:13,630 --> 00:14:20,730 I have to keep updating this now to equal the current exact time. 168 169 00:14:20,830 --> 00:14:29,560 So that means that, initially, this gets set to a value which is used to specify 1 second from now, and 169 170 00:14:29,560 --> 00:14:35,080 then I keep updating the clock to the current value of the clock and print "waiting..." 170 171 00:14:35,080 --> 00:14:41,230 until now is no longer less than 1 second from now. 171 172 00:14:41,230 --> 00:14:48,340 So I'll go ahead and comment out my for loop, and then run this. You'll see that it's gonna take a little 172 173 00:14:48,340 --> 00:14:53,650 bit of time because it's actually going to run this code quite a few times, in fact, 173 174 00:14:53,650 --> 00:14:57,550 3,974 times, and it printed "out waiting..." 174 175 00:14:57,550 --> 00:15:00,050 that many times. 175 176 00:15:00,100 --> 00:15:06,010 So this is an indication of just how fast these loops can actually run. 176 177 00:15:06,040 --> 00:15:11,860 Now, the reason why I say while loops are notoriously dangerous is because you have to make sure that 177 178 00:15:11,860 --> 00:15:18,820 this condition never ends up being continuously true until the end of time. Say, instead of checking while 178 179 00:15:18,820 --> 00:15:24,790 now is less than oneSecondFromNow, in which case it will actually stop after a second. If I instead 179 180 00:15:24,850 --> 00:15:31,780 checked a condition where it's always going to be true, say, 3 is greater than 2, until the end of 180 181 00:15:31,780 --> 00:15:35,000 time, 3 is still going to be greater than 2. 181 182 00:15:35,020 --> 00:15:39,790 Don't do this because your computer will actually crash. But I'm going to run it on my computer, just 182 183 00:15:39,790 --> 00:15:41,710 so you can see what happens. 183 184 00:15:41,710 --> 00:15:50,770 So when I hit run, you're going to see that it's going to continuously go many, many times and it's not 184 185 00:15:50,770 --> 00:15:56,650 really going to stop until the Mac realizes, well, actually this process has been going on for a long 185 186 00:15:56,650 --> 00:15:59,850 time and I probably should interrupt it. 186 187 00:16:00,070 --> 00:16:07,360 And in fact, even if you tried to stop the playground, it's actually not really going to stop your code 187 188 00:16:07,390 --> 00:16:13,270 because it's already running in the background.Aand at some point, Xcode actually just crashes. 188 189 00:16:13,270 --> 00:16:20,020 So while loops can generate these infinite loops, so you have to be really careful when you're working 189 190 00:16:20,020 --> 00:16:27,700 with them and ensure that the condition is clearly one that can turn false at one point. And the reason 190 191 00:16:27,700 --> 00:16:34,060 why you would use a while loop is because you have a certain condition that you know is eventually going 191 192 00:16:34,060 --> 00:16:38,500 to turn from true to false, but you don't know exactly when. 192 193 00:16:38,590 --> 00:16:40,990 So it could be something that is an unknown, 193 194 00:16:40,990 --> 00:16:45,990 say, I don't know how long it'll take for a particular image load from the internet, 194 195 00:16:46,000 --> 00:16:51,280 well, then maybe the while loop is something you could use. But I recommend trying to use the for loop, 195 196 00:16:51,610 --> 00:16:56,890 instead of the while loop at least when you're starting out, when you're unfamiliar with it, because it's 196 197 00:16:57,070 --> 00:17:03,700 a notorious source of bugs, and can generate these infinite loops of which mine is still going on, 197 198 00:17:03,700 --> 00:17:10,970 by the way, even if I try to tell it to stop. So after this lesson, I recommend having a read of the Swift 198 199 00:17:11,030 --> 00:17:18,260 Book on control flow and that's going to include For-In Loops as well as While Loops that we talked 199 200 00:17:18,260 --> 00:17:18,900 about. 200 201 00:17:19,010 --> 00:17:23,480 So just get a little bit more background on that. And then we'll head back and continue building out 201 202 00:17:23,510 --> 00:17:24,020 our app.