1 00:00:00,000 --> 00:00:06,400 [No Audio] 2 00:00:06,401 --> 00:00:09,566 This tutorial is about iterators. Iterators 3 00:00:09,567 --> 00:00:12,700 are objects that produce sequences of values, 4 00:00:12,733 --> 00:00:15,833 so they can be iterated or looped over. 5 00:00:16,400 --> 00:00:17,766 So if you are looping over 6 00:00:17,767 --> 00:00:20,833 something, you have already likely to be 7 00:00:20,834 --> 00:00:23,666 using an iterator. If you are transforming 8 00:00:23,667 --> 00:00:26,233 collections, you probably should be using 9 00:00:26,234 --> 00:00:28,833 them. In simple words, every time you ended 10 00:00:28,834 --> 00:00:31,566 up using a for loop in your program, you are 11 00:00:31,567 --> 00:00:34,400 most likely interacting with some kind of iterators. 12 00:00:34,401 --> 00:00:37,533 Iterators are a fairly central concept to Rust. 13 00:00:37,700 --> 00:00:39,600 So let's start learning its usage. 14 00:00:41,433 --> 00:00:44,000 Iterators will be typically used, based 15 00:00:44,001 --> 00:00:47,433 on the .iter function. Please note that we 16 00:00:47,434 --> 00:00:49,233 have already used this function when 17 00:00:49,234 --> 00:00:51,533 we were covering the topic of loops. However, 18 00:00:51,566 --> 00:00:53,633 we will be learning some interesting things 19 00:00:53,634 --> 00:00:56,033 about the same in this tutorial, let us see 20 00:00:56,034 --> 00:00:58,366 an example. I will create a vector first. 21 00:00:58,367 --> 00:01:02,733 [No Audio] 22 00:01:02,734 --> 00:01:04,533 Next, I will create an iterator on the 23 00:01:04,534 --> 00:01:06,766 collection that is vector in this case using 24 00:01:06,767 --> 00:01:08,133 the .iter function. 25 00:01:08,134 --> 00:01:12,700 [No Audio] 26 00:01:12,701 --> 00:01:14,000 The variable now is an 27 00:01:14,001 --> 00:01:16,600 iterator, which we can use to iterate through 28 00:01:16,601 --> 00:01:19,166 all the values of the vector. By default, it 29 00:01:19,167 --> 00:01:21,566 will not do anything useful, that is, they 30 00:01:21,567 --> 00:01:23,666 will become relevant only to us when we do 31 00:01:23,667 --> 00:01:26,500 some operation on them. In other words, they 32 00:01:26,501 --> 00:01:29,400 have no effect until you call methods that 33 00:01:29,401 --> 00:01:32,533 consume the iterators or use it up. For these 34 00:01:32,534 --> 00:01:34,666 reasons, they are also sometimes referred to as 35 00:01:34,667 --> 00:01:37,233 being lazy. Let us print the values of the 36 00:01:37,234 --> 00:01:41,533 variable iter and execute to see what it contains. 37 00:01:41,534 --> 00:01:49,233 [No Audio] 38 00:01:49,234 --> 00:01:50,866 You may note that, all the values of the 39 00:01:50,867 --> 00:01:53,800 vector are being captured by the iterator inside it. 40 00:01:54,100 --> 00:01:56,133 One of the key functions 41 00:01:56,134 --> 00:01:58,800 related to the iterator is the .next function. 42 00:01:59,066 --> 00:02:01,366 This function will return an Option enum. 43 00:02:01,566 --> 00:02:03,487 Let us use and print its value and execute. 44 00:02:03,488 --> 00:02:10,666 [No Audio] 45 00:02:10,667 --> 00:02:12,600 You may note that, it has returned to us the 46 00:02:12,601 --> 00:02:14,933 first value of the vector which is the value 47 00:02:14,934 --> 00:02:17,666 of one inside the some variant, calling this 48 00:02:17,667 --> 00:02:19,833 function again will return the next value 49 00:02:19,834 --> 00:02:22,133 inside the vector. Let us call it one more 50 00:02:22,134 --> 00:02:23,366 time and execute. 51 00:02:25,449 --> 00:02:27,000 It return the second value 52 00:02:27,633 --> 00:02:29,966 when there are no more values in the vector, 53 00:02:29,967 --> 00:02:32,100 and then the .next function will return 54 00:02:32,101 --> 00:02:33,766 the None variant, meaning that there is 55 00:02:33,767 --> 00:02:35,933 nothing left in the vector. Let me call it a 56 00:02:35,934 --> 00:02:39,294 few more times, so that we reach to the None variant. 57 00:02:39,295 --> 00:02:47,733 [No Audio] 58 00:02:47,734 --> 00:02:49,600 You may note that, it has printed all the 59 00:02:49,601 --> 00:02:51,866 values of the vector inside the Some variant, 60 00:02:51,867 --> 00:02:53,766 and for the last time it returned the None 61 00:02:53,767 --> 00:02:55,433 variant, meaning that there are no more 62 00:02:55,434 --> 00:02:58,333 values, there are a whole bunch of very 63 00:02:58,334 --> 00:03:00,466 useful functions that we can use with regards 64 00:03:00,467 --> 00:03:02,833 to the iterators. We will explain some of them 65 00:03:02,834 --> 00:03:05,418 now, I will start by declaring a vector. 66 00:03:05,419 --> 00:03:08,933 [No Audio] 67 00:03:08,934 --> 00:03:11,333 The first function we will explore is called the 68 00:03:11,366 --> 00:03:14,100 any function, this function will use a closure 69 00:03:14,101 --> 00:03:16,200 to determine if a certain condition is being 70 00:03:16,201 --> 00:03:19,100 met by any of the values. In case any of the 71 00:03:19,101 --> 00:03:21,600 values satisfies the condition, it will return 72 00:03:21,633 --> 00:03:23,700 a value of true, and in case none of the 73 00:03:23,701 --> 00:03:25,633 values satisfy the condition, then it will 74 00:03:25,634 --> 00:03:28,917 return a false. Let us use this function on the iterator. 75 00:03:28,918 --> 00:03:33,566 [No Audio] 76 00:03:33,567 --> 00:03:34,900 The input to this function is a 77 00:03:34,901 --> 00:03:36,866 closure, and inside the closure we need to 78 00:03:36,867 --> 00:03:39,066 mention a variable which will assume the 79 00:03:39,067 --> 00:03:42,100 values contained in the iterator one by one. 80 00:03:43,333 --> 00:03:45,800 Since this function operates on the 81 00:03:45,801 --> 00:03:48,033 values that are created using the .iter, 82 00:03:48,366 --> 00:03:51,166 which uses reference to the values itself are 83 00:03:51,167 --> 00:03:53,733 not the actual values. Therefore, we will 84 00:03:53,734 --> 00:03:56,466 pass the values by reference by writing &x. 85 00:03:57,366 --> 00:03:59,100 Next, I will check if any of the values is 86 00:03:59,101 --> 00:04:00,466 greater than 0 or not. 87 00:04:00,467 --> 00:04:03,720 [No Audio] 88 00:04:03,721 --> 00:04:04,666 It will check all 89 00:04:04,667 --> 00:04:06,833 the items or elements in the iterators one by 90 00:04:06,834 --> 00:04:09,066 one, and if any of the values satisfies the 91 00:04:09,067 --> 00:04:11,700 given condition. So it will return a true, and 92 00:04:11,701 --> 00:04:13,800 if none of the video satisfies the condition 93 00:04:13,801 --> 00:04:15,266 then it will return a false. 94 00:04:16,083 --> 00:04:17,536 Let us add a print statement to see the 95 00:04:17,537 --> 00:04:19,100 evaluation results of this function. 96 00:04:19,130 --> 00:04:25,900 [No Audio] 97 00:04:25,901 --> 00:04:28,766 The next useful function is the all function, 98 00:04:28,933 --> 00:04:31,633 let us use it. You may already note that, the 99 00:04:31,634 --> 00:04:33,400 output of this function is going to be of 100 00:04:33,401 --> 00:04:35,833 type bool. Since the variable check is of 101 00:04:35,834 --> 00:04:38,100 type bool. In particular, this function will 102 00:04:38,101 --> 00:04:40,800 return a true if all no elements satisfies 103 00:04:40,801 --> 00:04:42,933 the given condition. Let us add a suitable 104 00:04:42,934 --> 00:04:44,382 print statement and execute. 105 00:04:44,383 --> 00:04:51,400 [No Audio] 106 00:04:51,401 --> 00:04:53,333 The results is false since the condition is 107 00:04:53,334 --> 00:04:56,066 not being satisfied by all the elements, if we 108 00:04:56,067 --> 00:04:57,733 change the condition to date of greater than 109 00:04:57,734 --> 00:04:59,300 or equal to zero and execute again. 110 00:04:59,301 --> 00:05:04,433 [No Audio] 111 00:05:04,434 --> 00:05:06,133 There result is true in this case, as the 112 00:05:06,134 --> 00:05:08,066 condition is being satisfied by all the 113 00:05:08,067 --> 00:05:10,966 elements in this case, next is defined function. 114 00:05:11,566 --> 00:05:13,133 This function will search for an 115 00:05:13,166 --> 00:05:15,800 element that satisfies some condition 116 00:05:15,801 --> 00:05:17,933 mentioned using Closure. It will take a 117 00:05:17,934 --> 00:05:20,300 closure that returns an Option enum with the 118 00:05:20,301 --> 00:05:22,600 value inside it behind the reference, it 119 00:05:22,633 --> 00:05:24,700 applies this closure to each element of the 120 00:05:24,701 --> 00:05:28,066 iterator, and if any of them met the given 121 00:05:28,067 --> 00:05:31,000 condition, then finds function returns a sum 122 00:05:31,033 --> 00:05:33,900 element. If all returns false, then it 123 00:05:33,901 --> 00:05:36,433 returns an invariant. Please note that, 124 00:05:36,434 --> 00:05:38,866 defined will stop processing as soon as the 125 00:05:38,867 --> 00:05:41,033 condition inside the closure becomes true for 126 00:05:41,034 --> 00:05:43,366 a certain element. Let us use this function. 127 00:05:43,900 --> 00:05:46,633 Please note that I wrote a && sign in 128 00:05:46,634 --> 00:05:49,466 this case. This is because, as pointed out 129 00:05:49,467 --> 00:05:52,866 before, the .iter uses references so the values 130 00:05:52,867 --> 00:05:55,300 given to the function are behind reference. 131 00:05:55,500 --> 00:05:57,633 Moreover, the function also uses references 132 00:05:57,634 --> 00:06:00,166 to values so we are required to use double 133 00:06:00,167 --> 00:06:02,500 references to get the actual value, let us 134 00:06:02,501 --> 00:06:04,874 print the value of the variable check and execute. 135 00:06:04,875 --> 00:06:09,133 [No Audio] 136 00:06:09,134 --> 00:06:10,733 The first element which satisfies the 137 00:06:10,734 --> 00:06:12,766 given condition is being returned which has a 138 00:06:12,767 --> 00:06:16,266 value of one. Also note that the .any and 139 00:06:16,267 --> 00:06:18,733 .find functions has some similarities, but 140 00:06:18,734 --> 00:06:20,833 they are a bit different at the same time, the 141 00:06:20,834 --> 00:06:23,333 .any will return a Boolean value of true 142 00:06:23,334 --> 00:06:25,633 or false if the condition is being met by 143 00:06:25,634 --> 00:06:27,900 some value, while the .find function 144 00:06:27,901 --> 00:06:30,933 returns the value itself. Okay, great. So 145 00:06:30,934 --> 00:06:33,200 far, the next function is the position 146 00:06:33,201 --> 00:06:35,400 function, this will return the index or the 147 00:06:35,401 --> 00:06:37,533 position of the element satisfying a certain 148 00:06:37,534 --> 00:06:40,933 condition. In contrast to a find function, 149 00:06:40,966 --> 00:06:43,166 which returns the value this function will 150 00:06:43,167 --> 00:06:45,400 return the index or position of the value. 151 00:06:46,233 --> 00:06:48,300 It will take a closure and will check for 152 00:06:48,301 --> 00:06:50,433 certain condition, the function will stop 153 00:06:50,434 --> 00:06:52,433 processing as soon as the condition inside 154 00:06:52,434 --> 00:06:54,133 the closure becomes true for a certain 155 00:06:54,134 --> 00:06:56,533 element. The output of the function will be 156 00:06:56,534 --> 00:06:59,333 an Option enum, which will either return some 157 00:06:59,334 --> 00:07:02,266 position or index or None In case none of the 158 00:07:02,267 --> 00:07:04,666 value satisfies the given condition. Please 159 00:07:04,667 --> 00:07:06,466 note again that, the type of the variable 160 00:07:06,467 --> 00:07:09,300 check which stores the output and is not 161 00:07:09,301 --> 00:07:11,266 behind any reference, so, therefore, the 162 00:07:11,267 --> 00:07:13,466 input function is a simple reference. In 163 00:07:13,467 --> 00:07:15,766 fact, whenever we note a reference in the 164 00:07:15,767 --> 00:07:18,700 output, so, in those cases, we will be using 165 00:07:18,701 --> 00:07:20,433 double references since the input to the 166 00:07:20,434 --> 00:07:22,766 function itself is so behind the reference. 167 00:07:23,266 --> 00:07:26,200 Let's add a print statement to see the output and execute. 168 00:07:26,201 --> 00:07:33,766 [No Audio] 169 00:07:33,767 --> 00:07:35,766 The output in this case is the position or 170 00:07:35,767 --> 00:07:38,066 index four this is because the value five 171 00:07:38,067 --> 00:07:40,200 satisfies the condition that is greater than four. 172 00:07:40,433 --> 00:07:42,633 and it has the respective position or 173 00:07:42,634 --> 00:07:45,166 index of four since the index starts from 174 00:07:45,167 --> 00:07:48,266 zero and Rust. Now, sometimes we may be 175 00:07:48,267 --> 00:07:50,366 interested in finding out the index position 176 00:07:50,367 --> 00:07:52,733 from the ending part or from the extreme 177 00:07:52,734 --> 00:07:54,833 right in that case, there is another function 178 00:07:54,834 --> 00:07:57,166 called Or position which works exactly the 179 00:07:57,167 --> 00:07:59,566 same way but from the extreme right position, 180 00:07:59,933 --> 00:08:02,000 Let us use this function with the same condition. 181 00:08:02,001 --> 00:08:08,466 [No Audio] 182 00:08:08,467 --> 00:08:10,400 I will add a print statement and execute. 183 00:08:10,401 --> 00:08:16,633 [No Audio] 184 00:08:16,640 --> 00:08:19,007 The answer in this case is the ending index 185 00:08:19,008 --> 00:08:21,466 which is index 8 that is the extreme 186 00:08:21,467 --> 00:08:23,500 right first index satisfying the given 187 00:08:23,501 --> 00:08:25,766 condition. We will now go over some of the 188 00:08:25,767 --> 00:08:29,500 basic statistics related functions. The max 189 00:08:29,501 --> 00:08:31,700 function is used to find the maximum value 190 00:08:31,701 --> 00:08:35,265 within an iterable collection. Let us use this. 191 00:08:35,266 --> 00:08:42,566 [No Audio] 192 00:08:42,567 --> 00:08:44,300 The function returns an Option enum which 193 00:08:44,301 --> 00:08:46,700 will be either which will either return some 194 00:08:46,701 --> 00:08:50,033 maximum value or None if the iterator is empty. 195 00:08:51,000 --> 00:08:52,933 If several elements are equally 196 00:08:52,934 --> 00:08:55,300 maximum, the last element is returned, let 197 00:08:55,301 --> 00:08:57,133 us add a print statement and execute to see 198 00:08:57,134 --> 00:08:58,500 the output of the function. 199 00:08:58,501 --> 00:09:05,700 [No Audio] 200 00:09:05,701 --> 00:09:07,733 Similar to the max function, we have the min 201 00:09:07,734 --> 00:09:09,633 function its details are the same. 202 00:09:09,816 --> 00:09:10,966 So let me add the code. 203 00:09:10,967 --> 00:09:19,066 [No Audio] 204 00:09:19,067 --> 00:09:21,133 Next is the reverse function which is used to 205 00:09:21,134 --> 00:09:23,100 reverse the order of the values in the 206 00:09:23,133 --> 00:09:25,200 iterator, let us call this function 207 00:09:25,206 --> 00:09:33,266 [No Audio] 208 00:09:33,267 --> 00:09:35,366 The print statement will not show the values 209 00:09:35,367 --> 00:09:37,866 in the reverse order although its values are 210 00:09:37,867 --> 00:09:40,600 the are in the reverse order. Let me add a 211 00:09:40,601 --> 00:09:41,966 print statement and execute. 212 00:09:41,967 --> 00:09:48,366 [No Audio] 213 00:09:48,367 --> 00:09:50,600 You may note that, the values are not being shown 214 00:09:50,700 --> 00:09:53,533 to be in reverse order. However if I change 215 00:09:53,534 --> 00:09:56,419 the iter to iter.next and cargo run again. 216 00:09:56,420 --> 00:09:59,566 [No Audio] 217 00:09:59,567 --> 00:10:01,966 You may note that, the first value from the end 218 00:10:01,967 --> 00:10:04,966 is being shown to us inside the Some variant 219 00:10:04,967 --> 00:10:07,400 of the Option enum, which means that although 220 00:10:07,433 --> 00:10:10,000 the values are shown in regular order, they 221 00:10:10,001 --> 00:10:12,100 will be processed in the reverse order. 222 00:10:12,900 --> 00:10:15,000 Okay with this we end this tutorial because it is 223 00:10:15,001 --> 00:10:17,233 getting a bit lengthy and we will cover some 224 00:10:17,234 --> 00:10:19,266 of the other useful functions in the next 225 00:10:19,267 --> 00:10:21,433 lecture. So do can make again as the most 226 00:10:21,434 --> 00:10:23,238 important functions are yet to come. 227 00:10:23,239 --> 00:10:25,733 Until next tutorial, happy Rust programming. 228 00:10:25,734 --> 00:10:31,766 [No Audio]