1 00:00:00,000 --> 00:00:08,100 [No Audio] 2 00:00:08,101 --> 00:00:10,833 The concept of HashMap is present in almost 3 00:00:10,834 --> 00:00:14,000 all programming languages, it is a key value pair. 4 00:00:14,200 --> 00:00:15,900 With the help of the keys, we can get 5 00:00:15,901 --> 00:00:18,300 values of the map. Keys are unique with no 6 00:00:18,301 --> 00:00:20,200 duplicates allowed in the key, but the value 7 00:00:20,201 --> 00:00:22,933 can be duplicated. Some people use the 8 00:00:22,934 --> 00:00:24,933 analogy of dictionary for developing an 9 00:00:24,934 --> 00:00:27,800 understanding of HashMaps. The key in the 10 00:00:27,801 --> 00:00:30,000 HashMaps are like words of dictionary, and 11 00:00:30,001 --> 00:00:32,000 the values are the meaning of the words or 12 00:00:32,001 --> 00:00:34,900 keys. Okay with this, let us start learning 13 00:00:34,901 --> 00:00:37,933 HashMaps. HashMaps are part of the Rust 14 00:00:37,934 --> 00:00:40,900 standard library, we will include it by using 15 00:00:40,933 --> 00:00:42,300 its relevant module. 16 00:00:42,301 --> 00:00:47,733 [No Audio] 17 00:00:47,734 --> 00:00:50,400 Let us declare a simple HashMap, where I want 18 00:00:50,401 --> 00:00:52,400 to store the people names and their ages. 19 00:00:53,000 --> 00:00:55,200 This means that the people names will be the 20 00:00:55,201 --> 00:00:57,733 keys and the respective ages will be the values. 21 00:00:58,100 --> 00:00:59,633 Since people names are in a string 22 00:00:59,634 --> 00:01:01,933 format, so for the key part, I will use the 23 00:01:01,934 --> 00:01:05,400 string slices. Moreover, ages are numbers, so 24 00:01:05,401 --> 00:01:07,833 for the value part, I will mention i32. 25 00:01:09,200 --> 00:01:11,333 Next, I will call the new functions to have an 26 00:01:11,334 --> 00:01:12,700 empty HashMap. 27 00:01:12,733 --> 00:01:17,100 [No Audio] 28 00:01:17,101 --> 00:01:18,900 Let us add some values to the HashMap. 29 00:01:18,901 --> 00:01:22,200 [No Audio] 30 00:01:22,201 --> 00:01:23,700 The insert function is used to 31 00:01:23,701 --> 00:01:25,866 insert an entry into the HashMap, 32 00:01:25,867 --> 00:01:27,300 so let me insert my data. 33 00:01:27,301 --> 00:01:34,933 [No Audio] 34 00:01:34,934 --> 00:01:36,900 You may note a small k before the name, 35 00:01:36,901 --> 00:01:38,933 which is an indication from the Rust compiler, 36 00:01:38,934 --> 00:01:41,000 that it is going to be treated as a key. 37 00:01:41,001 --> 00:01:43,033 While a small v before the age, 38 00:01:43,034 --> 00:01:45,100 is an indication for the value part. 39 00:01:46,400 --> 00:01:48,066 I will add a couple of more entries. 40 00:01:48,067 --> 00:01:54,733 [No Audio] 41 00:01:54,734 --> 00:01:57,200 Let us now see how to access a specific value 42 00:01:57,201 --> 00:02:00,900 inside the HashMap. The get function will be 43 00:02:00,901 --> 00:02:03,100 used for accessing a particular entry, the 44 00:02:03,101 --> 00:02:05,000 input to the function will be a certain key 45 00:02:05,001 --> 00:02:07,300 and it will return its corresponding value. 46 00:02:07,633 --> 00:02:10,000 Let us use it to display inside a print statement. 47 00:02:10,032 --> 00:02:15,500 [No Audio] 48 00:02:15,501 --> 00:02:16,866 Let us execute. 49 00:02:16,867 --> 00:02:22,700 [No Audio] 50 00:02:22,701 --> 00:02:24,600 This gives me the value corresponding to the 51 00:02:24,601 --> 00:02:27,000 key. Please note that the get function will 52 00:02:27,001 --> 00:02:29,600 return an option enum, and we will use the 53 00:02:29,633 --> 00:02:32,200 unwrap function to uncover its value. 54 00:02:32,600 --> 00:02:35,200 Let us learn next, how to check if a certain key 55 00:02:35,201 --> 00:02:37,900 exists inside a HashMap. There are a couple of 56 00:02:37,901 --> 00:02:39,933 functions which can be used for this purpose. 57 00:02:40,266 --> 00:02:43,300 The first function is called the contains_key function. 58 00:02:43,800 --> 00:02:47,133 This function returns a Boolean value, if the key exists 59 00:02:47,134 --> 00:02:49,633 then it will return a true, and false 60 00:02:49,634 --> 00:02:51,733 otherwise. For example, I will use this 61 00:02:51,734 --> 00:02:54,400 function to check if the key of Nouman exists or not. 62 00:02:54,401 --> 00:02:56,400 [No Audio] 63 00:02:56,401 --> 00:02:57,900 If it exists, then I will print a 64 00:02:57,901 --> 00:03:00,000 suitable message, and in case it does not exist, 65 00:03:00,001 --> 00:03:01,533 then I will print another message. 66 00:03:01,534 --> 00:03:08,133 [No Audio] 67 00:03:08,134 --> 00:03:09,800 Let us cargo run this. 68 00:03:09,801 --> 00:03:15,033 [No Audio] 69 00:03:15,034 --> 00:03:17,600 The value exists in this case, the get 70 00:03:17,601 --> 00:03:20,400 function explained earlier can also be used 71 00:03:20,401 --> 00:03:22,400 for this purpose. For instance, I can use a 72 00:03:22,401 --> 00:03:24,733 match on the result of the get function, to 73 00:03:24,734 --> 00:03:26,133 check if the key corresponding 74 00:03:26,134 --> 00:03:27,400 to my name exists or not. 75 00:03:27,401 --> 00:03:34,733 [No Audio] 76 00:03:34,734 --> 00:03:37,700 The get may return either Some value or None. 77 00:03:37,701 --> 00:03:39,266 So, let me add the arms. 78 00:03:39,267 --> 00:03:47,300 [No Audio] 79 00:03:47,301 --> 00:03:50,333 The None arm indicates the key does not exist. 80 00:03:51,400 --> 00:03:53,533 Next let us look at how to iterate through 81 00:03:53,534 --> 00:03:56,000 all the key value pairs of the HashMap. 82 00:03:57,300 --> 00:03:59,800 To iterate through entries, we will use for loop. 83 00:03:59,801 --> 00:04:01,700 I will mention a couple of variables in the 84 00:04:01,701 --> 00:04:04,766 form of a tuple and we'll write in, followed 85 00:04:04,767 --> 00:04:06,900 by & sign and then person. 86 00:04:06,901 --> 00:04:12,100 [No Audio] 87 00:04:12,101 --> 00:04:14,233 The two variables will corresponds to the key 88 00:04:14,234 --> 00:04:16,233 and value parts respectively. 89 00:04:16,234 --> 00:04:18,565 I will display the keys and values 90 00:04:18,566 --> 00:04:20,200 inside the print statement next. 91 00:04:20,233 --> 00:04:26,600 [No Audio] 92 00:04:26,601 --> 00:04:28,400 Please note that in this case, we are using 93 00:04:28,401 --> 00:04:31,160 the references and not the actual values. 94 00:04:31,161 --> 00:04:33,305 This will ensure that the HashMap will be 95 00:04:33,306 --> 00:04:36,452 valid, after the end of the loop. Let us execute this. 96 00:04:36,453 --> 00:04:40,900 [No Audio] 97 00:04:40,901 --> 00:04:43,100 We have all the respective key value pairs. 98 00:04:44,300 --> 00:04:46,400 If we execute again, it is not 99 00:04:46,401 --> 00:04:48,500 necessary that the values will be printed in 100 00:04:48,501 --> 00:04:51,100 the same order as they are printed right now. 101 00:04:51,300 --> 00:04:52,833 Let me execute once more. 102 00:04:52,866 --> 00:04:56,533 [No Audio] 103 00:04:56,534 --> 00:04:57,800 You may note that, another 104 00:04:57,801 --> 00:05:00,233 name is now showing up as the first name. 105 00:05:00,234 --> 00:05:03,000 [No Audio] 106 00:05:03,001 --> 00:05:05,400 Now, let us learn what happens when 107 00:05:05,401 --> 00:05:08,100 we try to update the value at a specific key. 108 00:05:09,300 --> 00:05:11,200 I will first define a new HashMap which will 109 00:05:11,201 --> 00:05:13,600 represent the likes of people, so therefore 110 00:05:13,601 --> 00:05:16,133 the key and value are both in string formats. 111 00:05:16,134 --> 00:05:22,833 [No Audio] 112 00:05:22,834 --> 00:05:25,100 Let me add an entry into this HashMap. 113 00:05:25,101 --> 00:05:31,100 [No Audio] 114 00:05:31,101 --> 00:05:33,000 Let us see what will happen, if I update the 115 00:05:33,001 --> 00:05:34,200 value at the same key. 116 00:05:34,201 --> 00:05:36,333 [No Audio] 117 00:05:36,334 --> 00:05:37,933 I will update to mangoes. 118 00:05:37,934 --> 00:05:43,333 [No Audio] 119 00:05:43,334 --> 00:05:45,290 Let us print the HashMap and execute. 120 00:05:45,291 --> 00:05:52,734 [No Audio] 121 00:05:52,735 --> 00:05:55,400 It is only showing the updated value of mango 122 00:05:55,401 --> 00:05:57,900 for the key of Nouman, and not the value of apple. 123 00:05:58,133 --> 00:06:00,000 This means that when we update the 124 00:06:00,001 --> 00:06:01,800 value, the previous value will be 125 00:06:01,801 --> 00:06:04,000 overwritten. In contrast to the Insert 126 00:06:04,001 --> 00:06:05,800 Function, there is another useful function 127 00:06:05,801 --> 00:06:07,933 called the entry function, which works a 128 00:06:07,934 --> 00:06:11,566 little different. Let us comment out the previous lines. 129 00:06:13,333 --> 00:06:15,133 Let us use the entry function and update 130 00:06:15,134 --> 00:06:16,933 the likes of myself. 131 00:06:16,934 --> 00:06:19,133 We will use the entry function in connection 132 00:06:19,134 --> 00:06:21,200 with the or_insert function. 133 00:06:21,201 --> 00:06:26,633 [No Audio] 134 00:06:26,634 --> 00:06:29,500 This syntax will now only update the value of 135 00:06:29,501 --> 00:06:31,900 apple at the key of Nouman, if there is no 136 00:06:31,901 --> 00:06:34,400 value already existing at the specified key. 137 00:06:34,900 --> 00:06:36,700 In case the value exist, so it will not 138 00:06:36,701 --> 00:06:38,833 update the value. On the other hand, the 139 00:06:38,834 --> 00:06:41,433 Insert Function will always update the value. 140 00:06:42,200 --> 00:06:44,200 Let me add another value to the same key. 141 00:06:44,201 --> 00:06:49,733 [No Audio] 142 00:06:49,734 --> 00:06:51,533 In this case now, the value at the key will 143 00:06:51,534 --> 00:06:54,533 remain at the value of apple, and will not be 144 00:06:54,534 --> 00:06:57,400 updated to that of mango. Let us confirm this 145 00:06:57,401 --> 00:06:59,400 by using a print statement and execute. 146 00:06:59,401 --> 00:07:05,700 [No Audio] 147 00:07:05,701 --> 00:07:07,800 The key has not been updated, because there 148 00:07:07,801 --> 00:07:10,633 was, there was already a value of apple at the 149 00:07:10,634 --> 00:07:13,433 specified key. Let us now move to the final 150 00:07:13,434 --> 00:07:15,400 part of the tutorial, where we will be covering a 151 00:07:15,401 --> 00:07:17,500 nice example and use case of the HashMap. 152 00:07:17,501 --> 00:07:21,000 [No Audio] 153 00:07:21,001 --> 00:07:22,700 In this example, we will be first 154 00:07:22,701 --> 00:07:25,233 declaring a vector containing integer values. 155 00:07:25,800 --> 00:07:27,833 Then we will define a HashMap which will 156 00:07:27,834 --> 00:07:30,400 contain the distinct values inside the HashMaps 157 00:07:30,401 --> 00:07:33,000 as keys, and the frequencies of these 158 00:07:33,001 --> 00:07:34,700 distinct values are values. 159 00:07:35,733 --> 00:07:36,800 So, the key value 160 00:07:36,801 --> 00:07:39,033 pair will be the values of the vector along 161 00:07:39,034 --> 00:07:40,800 with their respective frequencies. 162 00:07:41,533 --> 00:07:43,500 This is going to be interesting, so let us start to 163 00:07:43,501 --> 00:07:46,000 code this. I will start by declaring a vector 164 00:07:46,001 --> 00:07:47,266 having some values. 165 00:07:47,267 --> 00:07:54,600 [No Audio] 166 00:07:54,601 --> 00:07:56,600 Next I will define an empty HashMap, whose 167 00:07:56,601 --> 00:07:59,066 values will be populated later on in the code. 168 00:07:59,067 --> 00:08:07,200 [No Audio] 169 00:08:07,201 --> 00:08:09,000 The keys will be the unique values in the 170 00:08:09,001 --> 00:08:11,333 vector, therefore they are of type i32, and 171 00:08:11,334 --> 00:08:12,900 the values are the frequencies of these 172 00:08:12,901 --> 00:08:16,033 values and are therefore defined as unsigned u32. 173 00:08:16,800 --> 00:08:18,300 I will next iterate through all the 174 00:08:18,301 --> 00:08:19,566 values of the vectors. 175 00:08:19,567 --> 00:08:26,300 [No Audio] 176 00:08:26,301 --> 00:08:28,400 I am using a reference to the vector values, 177 00:08:28,401 --> 00:08:30,900 which means that the vector some_vec 178 00:08:30,901 --> 00:08:32,732 will not lose the ownership, and its 179 00:08:32,733 --> 00:08:35,700 values will be used by reference. Inside the 180 00:08:35,701 --> 00:08:37,533 loop, I will examine the values inside the 181 00:08:37,534 --> 00:08:39,832 vector one by one. For each element of the 182 00:08:39,833 --> 00:08:41,900 vector, I will go to the corresponding key for 183 00:08:41,901 --> 00:08:43,900 that element and we'll add one to its 184 00:08:43,901 --> 00:08:46,400 frequency. To access the specific key 185 00:08:46,401 --> 00:08:48,600 corresponding to element in the vector, I will 186 00:08:48,601 --> 00:08:49,900 use the entry function. 187 00:08:49,901 --> 00:08:55,633 [No Audio] 188 00:08:55,634 --> 00:08:58,433 I used the star or deref operator, because the 189 00:08:58,434 --> 00:09:00,833 value of variable i is a reference and to 190 00:09:00,834 --> 00:09:03,700 access the value which it is pointing to, I 191 00:09:03,701 --> 00:09:06,933 need to dereference it. Next I will insert a 192 00:09:06,934 --> 00:09:09,300 default value of zero to this particular key, 193 00:09:09,301 --> 00:09:11,633 which is corresponding to a specific element 194 00:09:11,634 --> 00:09:16,033 of the vector, I will use the or_insert with a value of 0. 195 00:09:16,066 --> 00:09:23,000 [No Audio] 196 00:09:23,001 --> 00:09:24,900 When the loop executes for the first time, 197 00:09:24,901 --> 00:09:27,400 the value of i will be 5, and we will have 198 00:09:27,401 --> 00:09:29,700 a key of 5, for which we will have a 199 00:09:29,701 --> 00:09:31,800 default value of 0. In subsequent 200 00:09:31,801 --> 00:09:34,100 iterations, we would like to only update the 201 00:09:34,101 --> 00:09:36,833 value part only for this particular key. 202 00:09:37,533 --> 00:09:39,600 To do that, I will first declare a mutable 203 00:09:39,601 --> 00:09:41,200 reference to the value part of this 204 00:09:41,201 --> 00:09:43,833 particular entry. I will call it as freq. 205 00:09:43,834 --> 00:09:48,333 [No Audio] 206 00:09:48,334 --> 00:09:50,900 This means now that, whatever is being stored 207 00:09:50,901 --> 00:09:53,400 at the value part corresponding to the ith key, 208 00:09:53,401 --> 00:09:55,300 the freq is going to be pointing to that 209 00:09:55,301 --> 00:09:57,700 particular value using a mutable reference. 210 00:09:58,300 --> 00:10:01,100 So what I will do next is that, I will simply 211 00:10:01,101 --> 00:10:03,666 update the freq by a value of 1 in the next line. 212 00:10:03,667 --> 00:10:08,100 [No Audio] 213 00:10:08,101 --> 00:10:10,000 This may be a bit surprising for most 214 00:10:10,001 --> 00:10:12,600 of you, so I will explain it once more. When 215 00:10:12,601 --> 00:10:14,600 the loop executes, so we will have the first 216 00:10:14,601 --> 00:10:17,433 value of i being referring to the value of 5. 217 00:10:17,434 --> 00:10:20,833 When we use *i, it means a value of 5. 218 00:10:21,800 --> 00:10:23,400 So for the key part to being 219 00:10:23,401 --> 00:10:25,833 equal to 5, we will insert a value of 0. 220 00:10:26,400 --> 00:10:28,333 This is because the or_insert 221 00:10:28,334 --> 00:10:30,533 will insert a value, only when there is 222 00:10:30,534 --> 00:10:32,900 no value already existing for the same key. 223 00:10:33,500 --> 00:10:35,500 Next, we assign the mutable reference to the 224 00:10:35,501 --> 00:10:38,500 value part for the same key, to variable of freq. 225 00:10:39,333 --> 00:10:41,133 Finally, we update the value part for 226 00:10:41,134 --> 00:10:43,200 the same key, by a value of 1 using the 227 00:10:43,201 --> 00:10:45,700 statement *freq += 1. 228 00:10:46,533 --> 00:10:48,866 Outside the loop body, I will display the HashMap. 229 00:10:48,867 --> 00:10:52,500 [No Audio] 230 00:10:52,501 --> 00:10:54,700 Let us cargo run to see the program in action. 231 00:10:54,733 --> 00:11:00,300 [No Audio] 232 00:11:00,301 --> 00:11:03,000 We have the keys and their respective 233 00:11:03,001 --> 00:11:05,600 frequencies. The first value which is 5, is 234 00:11:05,601 --> 00:11:07,900 being repeated 6 times. In the same way, the 235 00:11:07,901 --> 00:11:10,033 value of 8 is being repeated 2 times. 236 00:11:10,100 --> 00:11:12,800 The value of 0, 1 time, and the value of 1, 2 times. 237 00:11:13,600 --> 00:11:15,600 This was just one possible use case of 238 00:11:15,601 --> 00:11:18,700 HashMaps. Of course they are used for 239 00:11:18,701 --> 00:11:20,733 a variety of different purposes in advanced 240 00:11:20,734 --> 00:11:23,100 topics such as associated arrays, database, 241 00:11:23,101 --> 00:11:26,133 indexing sets, transposition tables, and others. 242 00:11:27,000 --> 00:11:28,700 We will see some of its interesting 243 00:11:28,701 --> 00:11:30,600 uses in connection with trees and linked 244 00:11:30,601 --> 00:11:32,933 lists, in the real life problem solving section. 245 00:11:33,033 --> 00:11:35,000 HashMaps are quite fast, and when 246 00:11:35,001 --> 00:11:37,000 combined with some other complicated data 247 00:11:37,001 --> 00:11:40,000 types, can do wonders. Okay, that brings us to 248 00:11:40,001 --> 00:11:42,000 the end of this tutorial. We have learned 249 00:11:42,001 --> 00:11:44,600 HashMaps in this tutorial. Do come back 250 00:11:44,601 --> 00:11:46,500 for learning more and until next tutorial 251 00:11:46,501 --> 00:11:48,200 happy Rust programming. 252 00:11:48,201 --> 00:11:53,300 [No Audio]