[No Audio]
This tutorial is about iterators. Iterators
are objects that produce sequences of values,
so they can be iterated or looped over.
So if you are looping over
something, you have already likely to be
using an iterator. If you are transforming
collections, you probably should be using
them. In simple words, every time you ended
up using a for loop in your program, you are
most likely interacting with some kind of iterators.
Iterators are a fairly central concept to Rust.
So let's start learning its usage.
Iterators will be typically used, based
on the .iter function. Please note that we
have already used this function when
we were covering the topic of loops. However,
we will be learning some interesting things
about the same in this tutorial, let us see
an example. I will create a vector first.
[No Audio]
Next, I will create an iterator on the
collection that is vector in this case using
the .iter function.
[No Audio]
The variable now is an
iterator, which we can use to iterate through
all the values of the vector. By default, it
will not do anything useful, that is, they
will become relevant only to us when we do
some operation on them. In other words, they
have no effect until you call methods that
consume the iterators or use it up. For these
reasons, they are also sometimes referred to as
being lazy. Let us print the values of the
variable iter and execute to see what it contains.
[No Audio]
You may note that, all the values of the
vector are being captured by the iterator inside it.
One of the key functions
related to the iterator is the .next function.
This function will return an Option enum.
Let us use and print its value and execute.
[No Audio]
You may note that, it has returned to us the
first value of the vector which is the value
of one inside the some variant, calling this
function again will return the next value
inside the vector. Let us call it one more
time and execute.
It return the second value
when there are no more values in the vector,
and then the .next function will return
the None variant, meaning that there is
nothing left in the vector. Let me call it a
few more times, so that we reach to the None variant.
[No Audio]
You may note that, it has printed all the
values of the vector inside the Some variant,
and for the last time it returned the None
variant, meaning that there are no more
values, there are a whole bunch of very
useful functions that we can use with regards
to the iterators. We will explain some of them
now, I will start by declaring a vector.
[No Audio]
The first function we will explore is called the
any function, this function will use a closure
to determine if a certain condition is being
met by any of the values. In case any of the
values satisfies the condition, it will return
a value of true, and in case none of the
values satisfy the condition, then it will
return a false. Let us use this function on the iterator.
[No Audio]
The input to this function is a
closure, and inside the closure we need to
mention a variable which will assume the
values contained in the iterator one by one.
Since this function operates on the
values that are created using the .iter,
which uses reference to the values itself are
not the actual values. Therefore, we will
pass the values by reference by writing &x.
Next, I will check if any of the values is
greater than 0 or not.
[No Audio]
It will check all
the items or elements in the iterators one by
one, and if any of the values satisfies the
given condition. So it will return a true, and
if none of the video satisfies the condition
then it will return a false.
Let us add a print statement to see the
evaluation results of this function.
[No Audio]
The next useful function is the all function,
let us use it. You may already note that, the
output of this function is going to be of
type bool. Since the variable check is of
type bool. In particular, this function will
return a true if all no elements satisfies
the given condition. Let us add a suitable
print statement and execute.
[No Audio]
The results is false since the condition is
not being satisfied by all the elements, if we
change the condition to date of greater than
or equal to zero and execute again.
[No Audio]
There result is true in this case, as the
condition is being satisfied by all the
elements in this case, next is defined function.
This function will search for an
element that satisfies some condition
mentioned using Closure. It will take a
closure that returns an Option enum with the
value inside it behind the reference, it
applies this closure to each element of the
iterator, and if any of them met the given
condition, then finds function returns a sum
element. If all returns false, then it
returns an invariant. Please note that,
defined will stop processing as soon as the
condition inside the closure becomes true for
a certain element. Let us use this function.
Please note that I wrote a && sign in
this case. This is because, as pointed out
before, the .iter uses references so the values
given to the function are behind reference.
Moreover, the function also uses references
to values so we are required to use double
references to get the actual value, let us
print the value of the variable check and execute.
[No Audio]
The first element which satisfies the
given condition is being returned which has a
value of one. Also note that the .any and
.find functions has some similarities, but
they are a bit different at the same time, the
.any will return a Boolean value of true
or false if the condition is being met by
some value, while the .find function
returns the value itself. Okay, great. So
far, the next function is the position
function, this will return the index or the
position of the element satisfying a certain
condition. In contrast to a find function,
which returns the value this function will
return the index or position of the value.
It will take a closure and will check for
certain condition, the function will stop
processing as soon as the condition inside
the closure becomes true for a certain
element. The output of the function will be
an Option enum, which will either return some
position or index or None In case none of the
value satisfies the given condition. Please
note again that, the type of the variable
check which stores the output and is not
behind any reference, so, therefore, the
input function is a simple reference. In
fact, whenever we note a reference in the
output, so, in those cases, we will be using
double references since the input to the
function itself is so behind the reference.
Let's add a print statement to see the output and execute.
[No Audio]
The output in this case is the position or
index four this is because the value five
satisfies the condition that is greater than four.
and it has the respective position or
index of four since the index starts from
zero and Rust. Now, sometimes we may be
interested in finding out the index position
from the ending part or from the extreme
right in that case, there is another function
called Or position which works exactly the
same way but from the extreme right position,
Let us use this function with the same condition.
[No Audio]
I will add a print statement and execute.
[No Audio]
The answer in this case is the ending index
which is index 8 that is the extreme
right first index satisfying the given
condition. We will now go over some of the
basic statistics related functions. The max
function is used to find the maximum value
within an iterable collection. Let us use this.
[No Audio]
The function returns an Option enum which
will be either which will either return some
maximum value or None if the iterator is empty.
If several elements are equally
maximum, the last element is returned, let
us add a print statement and execute to see
the output of the function.
[No Audio]
Similar to the max function, we have the min
function its details are the same.
So let me add the code.
[No Audio]
Next is the reverse function which is used to
reverse the order of the values in the
iterator, let us call this function
[No Audio]
The print statement will not show the values
in the reverse order although its values are
the are in the reverse order. Let me add a
print statement and execute.
[No Audio]
You may note that, the values are not being shown
to be in reverse order. However if I change
the iter to iter.next and cargo run again.
[No Audio]
You may note that, the first value from the end
is being shown to us inside the Some variant
of the Option enum, which means that although
the values are shown in regular order, they
will be processed in the reverse order.
Okay with this we end this tutorial because it is
getting a bit lengthy and we will cover some
of the other useful functions in the next
lecture. So do can make again as the most
important functions are yet to come.
Until next tutorial, happy Rust programming.
[No Audio]