In Javascript everything looks like objects but there is another way of creating data in javascript knows as Maps. As type of Map() is objects but these are different from objects in many ways.
Maps Over Objects:
- Maps does not contain any keys by default.
- Maps are guaranteed to be ordered by the order they were inserted.
- The keys of a map can be anything, including a function, or even an object.
- They have better performance than objects on tasks which require rapid or frequent removal or addition of data.
- They are iterable by default.
Basic Operations Of Maps
Creating Map:
Any map in Javascript is initiated using the new Map() constructor.
let myMap = new Map();
Setting element in Javascript Map
To set a new value in map you need value with key associated with it.
let myMap = new Map();
myMap.set('firstKey', 'someValue');
Getting a key in a Javascript Map
To get the value of key, we have to use get().
let myMap = new Map();
myMap.set('firstKey', 'someValue');
console.log(myMap.get('firstKey'));
//someValue
Deleting an item in a Javascript Map
To delete a key in a map, we have to call the delete() method.
let myMap = new Map();
myMap.set('firstKey', 'someValue');
myMap.delete('firstKey');
Deleting all items in a Javascript Map
To delete the entire map altogether, leaving no items in it using clear():
let myMap = new Map();
myMap.set('firstKey', 'someValue');
myMap.clear()
console.log(myMap);
// Map(0)
Checking if a key exists in a Javascript Map
To check if a map has a certain key then we can use has() method:
let myMap = new Map();
myMap.set('firstKey', 'someValue');
console.log(myMap.has('firstKey'));
// true
Size of Javascript Map
To check the size of Javascript Map we have size method:
let myMap = new Map();
myMap.set('firstKey', 'someValue');
myMap.set('secondKey', 'someValue');
console.log(myMap.size);
// 2
Using Maps with non-string keys
As I mentioned, Javascript Maps allow non conventional keys, like functions and objects, whereas objects only allow strings and symbols. For example, this is valid in a map:
let myMap = new Map();
let myFunction = function() { return "someReturn"; }
myMap.set(myFunction, "value");
Map keys are based on reference, not value. That means although the following will work:
let myMap = new Map();
let myFunction = function() { return "someReturn"; }
myMap.set(myFunction, "value");
console.log(myMap.get(myFunction));
// "someReturn"
let myMap = new Map();
let myFunction = function() { return "someReturn"; }
myMap.set(myFunction, "value");
myMap.get(function() { return "someReturn"; });
// undefined
myMap.get('someReturn');
// undefined
That's because although function() { return "someReturn"; } and myFunction are the same in value, they are not the same in terms of where they are stored in system memory. So they are not exactly equivalent. Similarly, maps do not work on return value - so myFirstMap.get('someReturn') also returns undefined.
Merging Javascript Maps
If you have multiple maps you want to merge into one, you can merge them in the same way you merge objects - with the spread syntax. For example, here I merge myFirstMap and mySecondMap into myNewMap using the spread syntax:
let myFirstMap = new Map();
myFirstMap.set("some", "value");
let mySecondMap = new Map();
mySecondMap.set("someOther", "value");
let myNewMap = new Map([...myFirstMap, ...mySecondMap]);
console.log(myNewMap);
// Map(2) { some: "value", someOther: "value" }
Iterating Javascript Map with foreach
Maps are iterable by default. If we want to iterate over objects we usually have to use a function like Object.keys. We can use forEach on any map, like so:
let myFirstMap = new Map();
myFirstMap.set("some", "value");
myFirstMap.set("someOther", "value");
myFirstMap.forEach(function(value, key, map) {
// value -> the value of that key in the map
// key -> the key for this item in the map
// map -> the entire map
console.log(value, key, map);
})
// value some Map(2) {'some' => 'value', 'someOther' => 'value'}
// value someOther Map(2) {'some' => 'value', 'someOther' => 'value'}
Iterating Javascript Map using for
You can also iterate on a map using for(let ... of )! If you do that, each item is returned as an array of the key and value. Example:
let myFirstMap = new Map();
myFirstMap.set("some", "value");
for(let x of myFirstMap) {
console.log(x);
}
// [ 'some', 'value' ]
Iterating over values or keys in Javascript Maps
we can iterate over values or keys in Javascript is to use the values() or entries() methods. These return a new iterator for the values and items in a map respectively. That means we can access the next key or value using next() functions.
Example:
let myFirstMap = new Map();
myFirstMap.set("some", "value");
myFirstMap.set("someOther", "value");
myFirstMap.set("aFinal", "value");
let allKeys = myFirstMap.entries();
console.log(allKeys);
// MapIterator {'some' => 'value', 'someOther' => 'value', 'aFinal' => 'value'}
console.log(allKeys.next());
// { value: [ 'some', 'value' ], done: false }
console.log(allKeys.next().value);
// [ 'some', 'value' ]
Our return from allKeys.next() is an object. The value in this object is [ 'some', 'value' ] - an array of the first item in our map. We can keep running next() to get the following items in the map. Pretty cool! We can do the same thing again, with just values:
let myFirstMap = new Map();
myFirstMap.set("some", "value");
myFirstMap.set("someOther", "value");
myFirstMap.set("aFinal", "value");
let allValues = myFirstMap.values();
console.log(allValues);
//MapIterator {'value', 'value', 'value'}
console.log(allValues.next());
// { value: 'value' done: false }
console.log(allValues.next().value);
// 'value'
Serialization of Maps in Javascript
One of the drawbacks for some people which maps have, is that they cannot be easily serialized with JSON.parse() and JSON.stringify. Trying to do so results in an empty object, and this kind of makes sense - since the object of a Map is empty, if we only populate it with entries:
let myFirstMap = new Map();
myFirstMap.set("some", "value");
myFirstMap.set("someOther", "value");
myFirstMap.set("aFinal", "value");
console.log(JSON.stringify(myFirstMap));
// {}
The only realistic way to serialize a Map is to convert it to an object or array, which simply means you'll have to maintain some separate helper functions to do this task for you, should you use Maps. For example, we can use Array.from() to convert our Map to an array, and then use JSON.stringify() to serialize it:
let myFirstMap = new Map();
myFirstMap.set("some", "value");
myFirstMap.set("someOther", "value");
myFirstMap.set("aFinal", "value");
let arrayMap = Array.from(myFirstMap);
console.log(JSON.stringify(arrayMap));
// [["some","value"],["someOther","value"],["aFinal","value"]]