Hello World, Akwaaba π. In our previous post, we learnt about the Set
data structure, and how it can help you store unique values you can read about it here; we continue the lesson by looking at the next data structure Map
.
Even though, Object
can be used to store keyed collections , it is not enough in real life to handle complex data structures, that is why the Map
was introduced in the ES6.
Let's strengthen our JS muscles with some Map
s. πͺ
What is Map
Map is a collection of keyed data items, just like an
Object
. However,Map
allows us to use keys of any datatype
.
It is a data structure that we can use to map values
to keys
. Just like an Object
has a key: value
pair, it is the same with Map
, the only difference is that with Map
the key
can be of any type
. Which means strings
, arrays
and objects
can be used as keys
in Map
. Cool right π
Map Methods
The following methods and properties are available to use:
new Map()
map.set(key, value)
map.get(key)
map.has(key)
map.delete(key)
map.size
map.clear()
Alright, now that you know what a Map
is, let's see how to create one.
Creating a new Map
To create a map, use the syntax below
const myMap = new Map([iterable]);
Usually, it is best to create an empty map using the new Map()
syntax and then later add elements to the map using the set()
method
Adding elements to a map
To add elements to a map, use the set()
method.
The syntax is as below
map.set(key, value)
So let's create a user
map
let user = new Map();
console.log(user.set("name" ,"Emmanuel"));
/* key = "name", value = "Emmanuel" */
/*Map(1) {"name" => "Emmanuel"} */
In the above, we created a user
Map and added values to it, in the set()
method, we specify the key
of the map using a string
- name
and the value
was set to the string
, Emmanuel
.
Note that in Map
the key
can be of any data type so we could have used a Number
, Boolean
or an Object
as the key
.
Let's create another Map using a Number
as a key
let numeric = new Map();
console.log(numeric.set(1, "Used number as key"));
/*Map(1) {1 => "Used numbers as key"} */
Is Map Different from Object ?
Object
is very similar to Map
what distinguishes a Map
from an Object
is with that with the Map
the key can be of any data type
both primitive and reference type
can be used, whilst Object
only deals with primitive type
as keys
.
Now,let's take a scenario where we can use Object
as keys in a Map
.
Using Object as keys
Consider a scenario where you have some distinct user objects and you want to assign a role to each user. Meaning, you want the Object
to be the key
and the role the value
.
Let's see how you can achieve that using Map
let john = {name: "Johnson Tetteh"},
ama = {name: "Ama Brandson"},
kofi = {name: "Kofi Mensah"};
/* create the userRoles map */
let userRoles = new Map();
/* add elements to the map using the set , the set method is chainable*/
userRoles.set(john, "admin").set(ama,"editor").set(kofi, "super admin");
console.log(userRoles)
/* Map(3) {{β¦} => "admin", {β¦} => "editor", {β¦} => "super admin"}
[[Entries]]
0: {Object => "admin"}
1: {Object => "editor"}
2: {Object => "super admin"}
*/
What is happening above π
In the code above, we used the defined objects (john, ama and kofi) as keys
(which is one of the most notable and significant Map
feature because we cannot use Object as key in Object. String
as a key
in Object
is fine, but we canβt use another Object
as a key in Object
.) and we linked these keys to the needed values (which are the roles )
Get an element from a map
Ok, so let's say you have a Map
and you want to get a value
from it, how is that done ? π
Syntax
map.get(key)
The map.get(key)
method returns the value
of a map by the provided key.
Let's assume you want to get the role of Kofi in the userRoles
Map, let's see how that can be achieved
console.log(userRoles.get(kofi)) /* super admin */
Here we called the get()
method on the userRoles
Map and we passed in the key kofi
, doing so returns the value super admin
Checking the existence of an element.
So let take a situation where you have been given a Map
and you want to check is a given key
exists in the Map
. Let's see how to achieve that:
The map.has(key)
helps you to check if a key exists, it returns true
if the provided key exists, false
otherwise.
Let's still stay on the userRoles
map and check if the ama
key exists
userRoles.has(ama) /* true */
Count the number of elements
Ok, now we want to count the number of items in the Map
, how do we go about it ? π
Syntax
map.size
β returns the current element count.
The map.size
returns the number of elements in a map
Let's check how many elements we have in the userRoles
map
userRoles.size /* 3*/
Alternative approach to adding elements to a map
As described, you can add elements to a map using the map.set()
method, however this approach is not sustainable as you will have to continue chaining the set()
method to each call in order to create additional elements.
Let's see another way to populate a map when there are a lot of values to set
For instance, let's create a Map of all orderedMenu
in a restaurant and later get all the keys.
let orderedMenu = new Map([
['Fried Rice', 3],
["Potato fries", 4],
['Spaghetti', 1],
["Banku", 1]
]);
console.log(orderedMenu);
/* Map(4) {"Fried Rice" => 3, "Potato fries" => 4, "Spaghetti" => 1, "Banku" => 1} */
What is happening in the above π
We create a new map using the
new Map()
We pass it an
array
so we getnew Map([])
With the items in the
Array
, the first item will be thekey
, and the second item itsvalue
Iterating over Map keys
The map.keys()
method enables us loop over all the keys
in a map.
For instance, let's loop over all keys
in the orderedMenu
map above using the for... of
syntax
let orderedMenu = new Map([
['Fried Rice', 3],
["Potato fries", 4],
['Spaghetti', 1],
["Banku", 1]
]);
/* iterate over the keys (menu) */
for(let menu of orderedMenu.keys()){
console.log(menu)
}
/* Fried Rice Potato fries Spaghetti Banku */
Iterating over map values
Because Map
accepts any iterable
you can loop over all the values
in the Map
.
The map.values()
method enables us achieve that .
Taking the orderedMenu
Map, we can iterate over all the values
which is the number of menu to order for each menu.
Let's take a look.
for(let numOfMenu of orderedMenu.values()){
console.log(numOfMenu)
}
/* 3 4 1 1 */
Iterating over map elements / entries
The map.entries()
method gives you access to an array of [key,value]
pair of each element in the Map object. Meaning for each Map
you can get the entries(key and value) and store the items in an array using destructuring assignment
Using the orderedMenu
Map, let's iterate over the keys and values and print a nice message to the console.
for(let [menu, number] of orderedMenu.entries()){ /* use destructuring to get the key and value
into the variable number and menu respectively */
console.log(`You ordered ${number} , ${menu}`)
}
/*
You ordered 3 , Fried Rice
You ordered 4 , Potato fries
You ordered 1 , Spaghetti
You ordered 1 , Banku
*/
Creating Map from Object
If we an an Object
we can convert that Object
into Map
by utilizing the Object.entries(obj)
method.
The Object.entries(obj)
will return an array
of key/value
pair for a given Object
.
We then pass this array
into the new Map(iteraable)
method to create a Map
from an Object
.
Let's take a look at how that can be done.
let user = {
name: "John",
age: 30
};
/* return an array of key/value pairs */
console.log(Object.entries(user))
/* This creates an array from the object : (2) [Array(2), Array(2)] */
/* Pass the conversion from Object to array straight into the new Map() method */
let userMap = new Map(Object.entries(user)); /*to create a Map,
you need an array or iterable so this work* /
console.log(userMap);
/* Map(2) {"name" => "John", "age" => 30} */
Let's see what is happening here
We used the
Object.entries()
method to return an array of key/value pair[ ["name","John"], ["age", 30] ]
anArray
is exactly what is need to create aMap
Now, we pass the
Array
into thenew Map()
method to create the Map
Creating Object from Map
We learnt how to create Map
from Object
using the Object.entries()
method. π
We can use the Object.fromEntries
method where when given an Array
of [key, value]
pairs, it creates an Object
from them
let orderedMenu = Object.fromEntries([
['Fried Rice', 3],
["Potato fries", 4],
['Spaghetti', 1],
["Banku", 1]
])
console.log(orderedMenu);
/* We created an object from a map */
/* {Fried Rice: 3, Potato fries: 4, Spaghetti: 1, Banku: 1} */
Convert Map keys or values to a array
Let's still stick with the orderedMenu
map, and lets say we want to convert all the keys
in the map into an Array
.
Let's see how that can be achieved .
let orderedMenu = new Map ([
['Fried Rice', 3],
["Potato fries", 4],
['Spaghetti', 1],
["Banku", 1]
])
console.log(orderedMenu); /* creates a map object */
console.log(orderedMenu.keys());
/* logs all keys of the map object
{"Fried Rice", "Potato fries", "Spaghetti", "Banku"}
* /
/* Use the spread operator to unpack all the keys into single elements and store it in an array */
console.log([...orderedMenu.keys()]);
["Fried Rice", "Potato fries", "Spaghetti", "Banku"]
We can also follow the same steps to unpack all the values
of the map object into an array
let orderedMenu = new Map ([
['Fried Rice', 3],
["Potato fries", 4],
['Spaghetti', 1],
["Banku", 1]
])
console.log(orderedMenu); /* creates a map object */
console.log(orderedMenu.values()); /*Get all the values of the Map */
/* {3, 4, 1, 1} */
console.log([...orderedMenu.values()]); /*Unpack the values into an Array */
/* [3, 4, 1, 1] */
Whew, that was an exciting journey of Map
and Set
, if you are a bit confused, i recommend you take a break or go with the sleep therapy π΄ and come back later. It will all be very clearer
Summary
In summary
Map
is a collection of keyed data items, just like an Object. But the main difference is that Map allows keys of any type.Set
is also a collection , but withSet
, we are looking at collecting unique values or values without any repetition or duplicates.
Me daa se
PS: Akwaaba and Me daa se are Ghanaian π¬π dialect meaning, Welcome and Thank you respectively β€οΈ
Writing with love from π¬π