[JS] Data Types - Map and Set
1. Map
Map is a collection of keyed data items, just like an Object
.
The difference between Map
and Object
is that Map
allows keys of any type.
2. Map Methods
Here are the methods that can be used with Map
.
new Map()
- creates a new map.map.set(key, val)
- stores value by keymap.get(key)
- returns the value by key,undefined
ifkey
doesn’t exist.map.has(key)
- returnstrue
if key exits, otherwisefalse
.map.delete(key)
- removes the element (key/value pair) by key.map.clear()
- removes everything from the map.map.size
- return the current element count.
For example,
1
2
3
4
5
6
7
8
9
10
map.set('1', 'str1'); // a string key
map.set(1, 'num1'); // a numeric key
map.set(true, 'bool1'); // a boolean key
// remember the regular Object? it would convert keys to string
// Map keeps the type, so these two are different:
alert( map.get(1) ); // 'num1'
alert( map.get('1') ); // 'str1'
alert( map.size ); // 3
One thing here is to notice that unlike Objects
, Map
does not convert the key to strings!!
map[key]
isn’t the right way to use aMap
Although
map[key]
also works, this is treating amap
as anobject
, applying all corresponding limitations on anobject
(only string/symbol keys and so on).Hence, we should use
map
methods:set
,get
, and so on…
One important property of Map
is that it can use an object
as keys.
1
2
3
4
5
6
7
8
9
let john = { name: "John" };
// for every user, let's store their visits count
let visitsCountMap = new Map();
// john is the key for the map
visitsCountMap.set(john, 123);
alert( visitsCountMap.get(john) ); // 123
How
Map
compares keys
Map
uses roughly the same as strict equaility===
, but the difference is thatNaN
is considered equal toNaN
.Hence,
NaN
can be used as a key.
Chaining
Every
map.set
call returns the map itself, so we can chain the calls.
3. Map Iteration
There are 3 methods:
map.keys()
- returns an iterable for keys.map.values()
- returns an iterable for values.map.entries()
- returns an iterable for entries[key, val]
, used by default infor..of
.
For example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
let recipeMap = new Map([
['cucumber', 500],
['tomatoes', 350],
['onion', 50]
]);
// iterate over keys (vegetables)
for (let vegetable of recipeMap.keys()) {
alert(vegetable); // cucumber, tomatoes, onion
}
// iterate over values (amounts)
for (let amount of recipeMap.values()) {
alert(amount); // 500, 350, 50
}
// iterate over [key, value] entries
for (let entry of recipeMap) { // the same as of recipeMap.entries()
alert(entry); // cucumber,500 (and so on)
}
Map
preserves orderUnlike a regular
Object
where the order is not preserved,Map
preserves the order of values inserted.
Also, Map
has a forEach
method:
1
2
3
4
// runs the function for each (key, value) pair
recipeMap.forEach( (value, key, map) => {
alert(`${key}: ${value}`); // cucumber: 500 etc
});
4. Map from Object
1
2
3
4
5
6
7
8
let obj = {
name: "John",
age: 30
};
let map = new Map(Object.entries(obj));
alert( map.get('name') ); // John
Object.entries
returns the array of key/value pairs: [ ["name","John"], ["age", 30] ]
.
5. Object from Map
1
2
3
4
5
6
7
8
9
10
11
let map = new Map();
map.set('banana', 1);
map.set('orange', 2);
map.set('meat', 4);
let obj = Object.fromEntries(map.entries()); // make a plain object (*)
// done!
// obj = { banana: 1, orange: 2, meat: 4 }
alert(obj.orange); // 2
6. Set
A Set
is a collection of values where each value only occurs once.
It is much better for uniqueness checks.
7. Set Methods
new Set([iterable])
- creates a set, ifiterable
is provided, copies values from it into set.set.add(val)
- add a value and returns the set itself.set.delete(val)
- removes value, returntrue
ifvalue
existed, otherwisefalse
.set.has(val)
- returnstrue
if value exists, otherwisefalse
.set.clear()
- removes everything from the set.set.size
- total number of elements.
8. Iteration over Set
We can use for..of
or forEach
.
1
2
3
4
5
6
7
8
let set = new Set(["oranges", "apples", "bananas"]);
for (let value of set) alert(value);
// the same with forEach:
set.forEach((value, valueAgain, set) => {
alert(value);
});
forEach
has 3 arguments. This is for compatibility withMap
. This may help replaceMap
withSet
in the future.
Same methods Map
has for iterators are also supported:
set.keys()
- returns an iterable object for values.set.values()
- same asset.keys()
.set.entries()
- returns an iterable object for entries[val, val]
.