Hello World, Akwaaba ๐, you might have heard and used data types such as Arrays
and Objects
for storing a collection of items, but have you ever used Map
โ. In today's post let's talk a look at the Map object and how it can be used to store keyed collection. Let's get started.
What is the Map Object ?
I am sure you have encountered some data structures like Object and Arrays as a JS developer, whilst Arrays allow us to store ordered collections of items, Objects are used to store keyed collections.
Map is also a collection of keyed data items just like object, however Map allows us to store keys of any data type. A Map
contains a unique key and values mapped to that key
By definition, a Map
object holds key-value pairs where values of any type can be used either as keys or values.
The main difference between an Object
and a Map
is whereas Object
will store strings as keys, Map
can have a key of any data type (both primitive values and Object values). Map is mainly used for quickly searching and looking up data, in which each pair is in the format - (key, value)
Why the Map Object Was Introduced
Before ES6, when you need to map keys to values, Object
will be the preferred, because it allows you to map a key to a value of any type. However, there were some side effects with the use of Objects.
Every object has a default key, the prototype which can collide with your own keys if you're not careful.
Map
however, does not contain any default keys. It only contain keys you explicitly give itIn
Objects
, the keys must be either strings or a symbols, it is not possible to use objects as keys. However, inMap
, the keys can be of any value. You can use object , strings or even functions as keys- The number of items in a
Map
can easily be retrieved using its size property, in contrast, determining the number of items in anObject
must be done manually.
Useful Map() methods and properties
Now that you have understood why the concept of Map
was introduced, let's now take a look at some of the methods and properties.
new Map()
: This creates the mapmap.set(key, value)
: Use this method to add new elements. It stores the value by the given key. But if you pass an existing key, it will overwrite the value mapped to that key with the new value โ as what set operation is supposed to do.map.get(key)
: It returns the value by the given key, if the key doesn't exist in the map, it returnsundefined
, which means we need to know the key in order to get the valuemap.has(key)
: It returnstrue
if the key exists,false
otherwisemap.delete(key)
: It removes the value by the keymap.clear()
: It removes everything from the map -map.size
: It returns the current element count
Below, we take a look at how to create a map
Creating the Map
To create a map, we use the built-in constructor and new syntax.
let myMap = new Map()
console.log(myMap) /* {} You get an Object because Map is essentially an Object*/
/*We can also pass an iterable to the map */
let myMap = new Map([["Kwasi", 2],["Ama", 40]])
console.log(myMap)
/*
It creates a map object with keys as strings mapped to the values
Map(2) {"Kwasi" => 2, "Ama" => 40}
*/
Examples of Using Map
Let's take a scenario where you have 3 user objects who have access to the backend of a web app. Each user Object
has fullname
and email
as keys.
Our task will be to assign roles to each user, meaning we want to create a map of users and roles.
Let see how to achieve that using Map
๐
/*define the user objects */
let Kofi = {fullName: "Kofi Ackon", email: "kofi@gmail.com"}
let Ama = {fullName: "Ama Ataa", email: "ama2@gmail.com"}
let Kwame = {fullName: "Kwame Takyi", email: "kwame@yahoo.com"}
/*create an instance of the map object */
let userRoles = new Map()
/*assign each a role to each user using the map.set(key, value)
The key for each user will now be the object defined as above
The value will be role you are assigning to each user.
What this means is we are basically using objects as keys and map it to a value
*/
/*To assign a role to each user, you use the .set(key,value) method on the instance of the map*/
userRoles.set(Kofi, "admin")
userRoles.set(Ama, 'editor')
userRoles.set(Kwame, 'contributor')
console.log(userRole) /* This returns a Map with key-value collection
just like an Object will, but in this case the key is an Object and not a string
Map(3) {{โฆ} => "admin", {โฆ} => "editor", {โฆ} => "contributor"}
*/
Get an element from a map
Now that we have the userRole
map , we can get some values from it.
Let say you want to see the role of Ama, you will use the map.get(key)
and that will return the value
of the given key
(key in this case is Ama)
console.log(userRoles.get(Ama))
/* The code above returns the 'editor' value */
Checking the existence of an element
As defined earlier, we can use the map.has(key)
method to check if a key exists. It returns true
if it exists and false
otherwise.
The code below will check if a key exist using the userRoles
map
userRoles.has(Ama) /* returns true */
userRoles.has(Leslie) /*returns false */
Get the number of elements in the map
The map.size()
method returns the number of elements in the map.
The code below checks the number of elements in the userRoles
map
console.log(userRoles.size) /* returns 3 */
Iteration Over Map
There are three methods that can be use to loop over a map
map.keys()
map.values()
map.entries()
How to loop over map keys
You can use the keys()
method to get the keys of a map
object. The keys()
method returns a new iterator object that contains the keys of elements in the map.
In the code below, we get all the keys in the userSavings
map object
let userSavings = new Map([
["Kofi", 400], ["Ama", 900], ["Esi" ,50]
]) /*using iterables*/
/*loop over all the keys */
for(let user of userSavings.keys()){
console.log(user) /*Kofi, Ama, Esi */
}
Using our earlier userRoles
map, we can also get the fullname keys. Remember we set an object
as key
so we need to access the object
during the iteration and then get the property we need which in this case will be the fullname
for(let userObj of userRoles.keys()){
console.log(userObj.fullname) /* Kofi Ackon, Ama Ataa, Kwame Takyi */
}
/*Since the key itself is an object, we use the dot notation to access the fullname
property in order to have access to the need key*/
How to loop over map values
You can also use the map.values()
method to have access to all the values of all elements in the map object.
The code below grabs all the values of the userSavings
map
let userSavings = new Map([
["Kofi", 400], ["Ama", 900], ["Esi" ,50]
])
/*iterate over all the values */
for(let savings of userSavings.values()){
console.log(savings) /* 400 900 50 */
}
Now, let' s iterate over all the roles assigned to the users in the userRoles
map ๐
/*iterate over all the values of the userRoles map object */
for(let roles of userRoles.values()){
console.log(roles)
}
How to delete a key from a map object
Use the .delete()
method to delete an entry in the map. When an entry has been deleted it returns true
So let's say in the userRoles
map we want to delete the Kofi
key , how can we achieve that ? ๐
The code below deletes the Kofi
key from the userRoles
userRoles.delete(Kofi) /* true*/
With the key delete, the number of elements will reduce, let's check it out
console.log(userRoles.size) /*2*/
In Conclusion, which is better ? ๐
So which one is better, map vrs object ? Well, it really depends on what kind of data you are going to work on and what operations you will be performing on them.
Object is a great choice for situations where you only need a simple structure to store data and you know the keys will either be a string or symbol. Also in certain situations were you have to work with JSON, object is a preferred option.
Map helps to preserve the order of keys and tends to perform better in storing large sets of data. I guess one of the biggest advantage of map is, it allows to use keys of any type.
So tell me, which one will you prefer ? Map
vrs Object
. Me daa se ๐
P.S " Akwaaba" and "Me daa se" is a Ghanaian ๐ฌ๐ญ local dialect meaning "Welcome" and "Thank You" respectively