Set and Map data structures
Set
Set is a new data structure of es6. It is similar to array, but the values of members are unique and there are no duplicate values.
Set itself is a constructor used to generate a set data structure
Usage:
const s = new Set(); [1,2,3,3,2,1,6].forEach(x => s.add(x)); for(let i of s){ console.log(i);//1 2 3 6 }
The above code adds members to the Set structure through the add() method. The results show that the Set structure will not add duplicate values.
The Set function can accept an array (or other data structures with iterable interface) as a parameter for initialization.
//Take array as parameter const items =new Set([1,2,3,4,5,5,5,5]); //Take class array object as parameter const set=new Set(document.querySelectorAll('div'));
Note: for Set, 5 and '5' are two different values, while NaN is the same value.
Set instance properties and methods
An instance of the Set structure has the following properties.
- Set.prototype.constructor: constructor, which is set function by default.
- Set.prototype.size: returns the total number of members of the set instance.
The methods of Set instances are divided into two categories: operation methods (for manipulating data) and traversal methods (for traversing members).
Operation method
- Set.prototype.add(value): adds a value and returns the set structure itself.
- Set.prototype.delete(value): deletes a value and returns a Boolean value indicating whether the deletion is successful.
- Set.prototype.has(value): returns a Boolean value indicating whether the value is a member of set.
- Set.prototype.clear(): clear all members without return value.
Note: the Set structure is not an array, but array The from method can convert a Set structure into an array. In fact, in this way, you can remove the duplication by converting the original array into a Set structure, and then through array From converts the Set structure into an array. This enables array de duplication.
Traversal operation
- Set.prototype.keys(): the iterator that returns the key name
- Set.prototype.values(): the iterator that returns the key value
- Set.prototype.entries(): returns the traversal of key value pairs
- Set.prototype.forEach(): use the callback function to traverse each member
Note: the traversal order of Set is the insertion order.
Note: the keys method, values method and entries method all return ergodic objects. So you also need to use the method of traversing the iterator object to access the value inside.
Note: since the Set structure has no key name but only key value (or the key name and key value are the same value), the behaviors of the keys method and the values method are exactly the same.
let set = new Set([111,222,333]); console.log(set.keys()); console.log(set.values());
Specific traversal methods, I recommend using for of,
let set = new Set([111,222,333]); for(let item of set.keys()){ console.log(item);//111 222 333 }//set.values() is the same as the above output, so there is no example
Specific usage of the entries method
let set = new Set([111, 222, 333]); console.log(set.entries()); for (let item of set.entries()) { console.log(item); }
Therefore, it can be said that the Set key name and key value are the same value
Note: in fact, the instance of Set structure is traversable by default, which means that you can directly use for Of loop through Set.
let set = new Set([111, 222, 333]); for (let item of set) { console.log(item);//111 222 333 }
Did the careful students find that this is the same as using for The result of the of loop traversing the iterator object returned by the keys method and the values method is the same.
In fact, the default ergodic generation function of Set is its values method.
Instances of the Set structure can also be traversed using the method of forEach()
let set=new Set([1,4,9]); set.forEach((value, key)=> console.log(key +' : '+ value)) //1 : 1 //4 : 4 //9 : 9 //Write the following for better understanding const set = new Set([ ['foo', 1], ['bar', 2] ]); for (let item of set.keys()) { console.log(item); } //["foo",1] //["bar",2] //From set. By deconstructing the assignment Keys() gets k and v for (let [k, v] of set.keys()) { console.log(k, v); } //foo 1 //bar 2 //The first parameter [] takes the key value of set, that is ["foo",1]. In fact, the key is the same value set.forEach( ([key, value]) => console.log(key, value) ) //foo 1 //bar 2 //The value and key output here are actually the same value set.forEach( (value, key) => console.log(value, key) )
The above code shows that the parameter of the forEach method is a processing function. The parameters of this function are consistent with the forEach of the array, followed by the key value, key name and the Set itself (this parameter is omitted in the above example). It should be noted here that the key name of the Set structure is the key value (both are the same value), so the value of the first parameter and the second parameter are always the same.
Map
Map is a se6 new data structure. It is similar to an Object and a collection of key value pairs, but the range of "key" is not limited to strings. Various types of values (including objects) can be used as keys. This makes up for the disadvantage that the Object structure can only correspond to "string value". The map structure provides "value value" correspondence, which is a more perfect implementation of Hash structure.
const m = new Map(); const o = {p: 'Hello World'}; m.set(o, 'content') m.get(o) // "content" m.has(o) // true m.delete(o) // true m.has(o) // false
The above code uses the set method of the Map structure to treat the object o as a key of m, then uses the get method to read the key, and then uses the delete method to delete the key.
The above example shows how to add members to a Map. As a constructor, Map can also accept an array as a parameter. The members of the array are arrays representing key value pairs. The details are as follows:
const map = new Map([ ['name', 'Zhang San'], ['title', 'Author'] ]); map.size // 2 map.has('name') // true map.get('name') // "Zhang San" map.has('title') // true map.get('title') // "Author"
I wonder why such a two-dimensional array specifies two keys name and title when creating a new Map instance.
In fact, the Map constructor takes an array as a parameter and actually executes the following algorithm.
const items = [ ['name', 'Zhang San'], ['title', 'Author'] ]; const map = new Map(); items.forEach( ([key, value]) => map.set(key, value) );
Specifically, each array item in the items is obtained through the forEach() method, such as: [name ',' Zhang San], and then the array item is deconstructed and assigned to [key,value], that is, at this time, the key has been 'name' and the value has been 'Zhang San', and then through the set() method, the key is used as a key of the map, and the value is the key value of the key.
In fact, not only arrays, but any data structure with an Iterator interface and each member is a two element array (see the chapter "Iterator") can be used as parameters of the Map constructor. That is to say, both Set and Map can be used to generate a new Map.
const set = new Set([ ['foo', 1], ['bar', 2] ]); const m1 = new Map(set); m1.get('foo') // 1 const m2 = new Map([['baz', 3]]); const m3 = new Map(m2); m3.get('baz') // 3
You may wonder why you can generate a new Map like this
In fact, if all the above are understood, it is easier to understand:
In fact, through XXX forEach(([key, value]) => yyy. set(key, value)); Generated in this way (done at the bottom). As long as you can traverse in this way, you can generate a new Map.
If the same key is assigned multiple times, the subsequent value will overwrite the previous value.
const map =newMap(); map.set(1,'aaa'); map.get(1)//"aaa" map.set(1,'bbb'); map.get(1)// "bbb"
Note: the key of Map is actually bound to the memory address. As long as the memory address is different, it is regarded as two keys.
//Example 1 const map =newMap(); const k1 =['a']; const k2 =['a']; map .set(k1,111) .set(k2,222); map.get(k1)// 111 map.get(k2)// 222 //Example 2 const map =newMap(); map.set(['a'],555); map.get(['a'])// undefined
If the key of a Map is a simple type of value (number, string, Boolean value), as long as the two values are strictly equal, the Map regards it as a key. For example, 0 and - 0 are one key, and the Boolean value true and string true are two different keys. In addition, undefined and null are also two different keys. Although NaN is not strictly equal to itself, Map treats it as the same key.
Properties and operation methods of Map structure
size attribute
The size property returns the total number of members of the Map structure
Map.prototype.set(key, value)
The set method sets the key value corresponding to the key name key to value, and then returns the entire Map structure. If the key already has a value, the key value will be updated, otherwise the key will be newly generated. The set method returns the current Map object, so it can be written in chain. Let Map = new Map() set(1,'a'). set(2,'b'). set(3,'c');
Map.prototype.get(key)
The get method reads the key value corresponding to the key. If the key cannot be found, it returns undefined.
Map.prototype.has(key)
The has method returns a Boolean value indicating whether a key is in the current Map object.
Map.prototype.delete(key)
The delete method deletes a key and returns true. If the deletion fails, false is returned.
Map.prototype.clear()
The clear method clears all members and returns no value.
traversal method
- Map.prototype.keys(): the iterator that returns the key name.
- Map.prototype.values(): the iterator that returns the key value.
- Map.prototype.entries(): returns the traversal of all members.
- Map.prototype.forEach(): traverse all members of the map.
Note: the traversal order of the Map is the insertion order.
const map =new Map([ ['F','no'], ['T','yes'], ]); console.log(map); //Map(2){"F" => "no","T" => "yes"} for(let key of map.keys()){ console.log(key); } // "F" // "T" for(let value of map.values()){ console.log(value); } // "no" // "yes" for(let item of map.entries()){ console.log(item[0], item[1]); } // "F" "no" // "T" "yes" // perhaps for(let [key, value] of map.entries()){ console.log(key, value); } // "F" "no" // "T" "yes" // Equivalent to using map entries() for(let [key, value] of map){ console.log(key, value); } // "F" "no" // "T" "yes"
The last example of the above code represents the default iterator interface (Symbol.iterator attribute) of the Map structure, which is the entries method.
In addition, Map also has a forEach method, which is similar to the forEach method of array, and can also be traversed.
map.forEach(function(value, key, map){ console.log("Key: %s, Value: %s", key, value); }); //Key:F,Value:no //Key:T,Value:yes
If you want to learn more deeply, it is recommended to see Ruan Yifeng's tutorial
https://www.bookstack.cn/read/es6-3rd/spilt.3.docs-set-map.md