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.
