[No Audio]
The concept of HashMap is present in almost
all programming languages, it is a key value pair.
With the help of the keys, we can get
values of the map. Keys are unique with no
duplicates allowed in the key, but the value
can be duplicated. Some people use the
analogy of dictionary for developing an
understanding of HashMaps. The key in the
HashMaps are like words of dictionary, and
the values are the meaning of the words or
keys. Okay with this, let us start learning
HashMaps. HashMaps are part of the Rust
standard library, we will include it by using
its relevant module.
[No Audio]
Let us declare a simple HashMap, where I want
to store the people names and their ages.
This means that the people names will be the
keys and the respective ages will be the values.
Since people names are in a string
format, so for the key part, I will use the
string slices. Moreover, ages are numbers, so
for the value part, I will mention i32.
Next, I will call the new functions to have an
empty HashMap.
[No Audio]
Let us add some values to the HashMap.
[No Audio]
The insert function is used to
insert an entry into the HashMap,
so let me insert my data.
[No Audio]
You may note a small k before the name,
which is an indication from the Rust compiler,
that it is going to be treated as a key.
While a small v before the age,
is an indication for the value part.
I will add a couple of more entries.
[No Audio]
Let us now see how to access a specific value
inside the HashMap. The get function will be
used for accessing a particular entry, the
input to the function will be a certain key
and it will return its corresponding value.
Let us use it to display inside a print statement.
[No Audio]
Let us execute.
[No Audio]
This gives me the value corresponding to the
key. Please note that the get function will
return an option enum, and we will use the
unwrap function to uncover its value.
Let us learn next, how to check if a certain key
exists inside a HashMap. There are a couple of
functions which can be used for this purpose.
The first function is called the contains_key function.
This function returns a Boolean value, if the key exists
then it will return a true, and false
otherwise. For example, I will use this
function to check if the key of Nouman exists or not.
[No Audio]
If it exists, then I will print a
suitable message, and in case it does not exist,
then I will print another message.
[No Audio]
Let us cargo run this.
[No Audio]
The value exists in this case, the get
function explained earlier can also be used
for this purpose. For instance, I can use a
match on the result of the get function, to
check if the key corresponding
to my name exists or not.
[No Audio]
The get may return either Some value or None.
So, let me add the arms.
[No Audio]
The None arm indicates the key does not exist.
Next let us look at how to iterate through
all the key value pairs of the HashMap.
To iterate through entries, we will use for loop.
I will mention a couple of variables in the
form of a tuple and we'll write in, followed
by & sign and then person.
[No Audio]
The two variables will corresponds to the key
and value parts respectively.
I will display the keys and values
inside the print statement next.
[No Audio]
Please note that in this case, we are using
the references and not the actual values.
This will ensure that the HashMap will be
valid, after the end of the loop. Let us execute this.
[No Audio]
We have all the respective key value pairs.
If we execute again, it is not
necessary that the values will be printed in
the same order as they are printed right now.
Let me execute once more.
[No Audio]
You may note that, another
name is now showing up as the first name.
[No Audio]
Now, let us learn what happens when
we try to update the value at a specific key.
I will first define a new HashMap which will
represent the likes of people, so therefore
the key and value are both in string formats.
[No Audio]
Let me add an entry into this HashMap.
[No Audio]
Let us see what will happen, if I update the
value at the same key.
[No Audio]
I will update to mangoes.
[No Audio]
Let us print the HashMap and execute.
[No Audio]
It is only showing the updated value of mango
for the key of Nouman, and not the value of apple.
This means that when we update the
value, the previous value will be
overwritten. In contrast to the Insert
Function, there is another useful function
called the entry function, which works a
little different. Let us comment out the previous lines.
Let us use the entry function and update
the likes of myself.
We will use the entry function in connection
with the or_insert function.
[No Audio]
This syntax will now only update the value of
apple at the key of Nouman, if there is no
value already existing at the specified key.
In case the value exist, so it will not
update the value. On the other hand, the
Insert Function will always update the value.
Let me add another value to the same key.
[No Audio]
In this case now, the value at the key will
remain at the value of apple, and will not be
updated to that of mango. Let us confirm this
by using a print statement and execute.
[No Audio]
The key has not been updated, because there
was, there was already a value of apple at the
specified key. Let us now move to the final
part of the tutorial, where we will be covering a
nice example and use case of the HashMap.
[No Audio]
In this example, we will be first
declaring a vector containing integer values.
Then we will define a HashMap which will
contain the distinct values inside the HashMaps
as keys, and the frequencies of these
distinct values are values.
So, the key value
pair will be the values of the vector along
with their respective frequencies.
This is going to be interesting, so let us start to
code this. I will start by declaring a vector
having some values.
[No Audio]
Next I will define an empty HashMap, whose
values will be populated later on in the code.
[No Audio]
The keys will be the unique values in the
vector, therefore they are of type i32, and
the values are the frequencies of these
values and are therefore defined as unsigned u32.
I will next iterate through all the
values of the vectors.
[No Audio]
I am using a reference to the vector values,
which means that the vector some_vec
will not lose the ownership, and its
values will be used by reference. Inside the
loop, I will examine the values inside the
vector one by one. For each element of the
vector, I will go to the corresponding key for
that element and we'll add one to its
frequency. To access the specific key
corresponding to element in the vector, I will
use the entry function.
[No Audio]
I used the star or deref operator, because the
value of variable i is a reference and to
access the value which it is pointing to, I
need to dereference it. Next I will insert a
default value of zero to this particular key,
which is corresponding to a specific element
of the vector, I will use the or_insert with a value of 0.
[No Audio]
When the loop executes for the first time,
the value of i will be 5, and we will have
a key of 5, for which we will have a
default value of 0. In subsequent
iterations, we would like to only update the
value part only for this particular key.
To do that, I will first declare a mutable
reference to the value part of this
particular entry. I will call it as freq.
[No Audio]
This means now that, whatever is being stored
at the value part corresponding to the ith key,
the freq is going to be pointing to that
particular value using a mutable reference.
So what I will do next is that, I will simply
update the freq by a value of 1 in the next line.
[No Audio]
This may be a bit surprising for most
of you, so I will explain it once more. When
the loop executes, so we will have the first
value of i being referring to the value of 5.
When we use *i, it means a value of 5.
So for the key part to being
equal to 5, we will insert a value of 0.
This is because the or_insert
will insert a value, only when there is
no value already existing for the same key.
Next, we assign the mutable reference to the
value part for the same key, to variable of freq.
Finally, we update the value part for
the same key, by a value of 1 using the
statement *freq += 1.
Outside the loop body, I will display the HashMap.
[No Audio]
Let us cargo run to see the program in action.
[No Audio]
We have the keys and their respective
frequencies. The first value which is 5, is
being repeated 6 times. In the same way, the
value of 8 is being repeated 2 times.
The value of 0, 1 time, and the value of 1, 2 times.
This was just one possible use case of
HashMaps. Of course they are used for
a variety of different purposes in advanced
topics such as associated arrays, database,
indexing sets, transposition tables, and others.
We will see some of its interesting
uses in connection with trees and linked
lists, in the real life problem solving section.
HashMaps are quite fast, and when
combined with some other complicated data
types, can do wonders. Okay, that brings us to
the end of this tutorial. We have learned
HashMaps in this tutorial. Do come back
for learning more and until next tutorial
happy Rust programming.
[No Audio]