Set
basic usage
A set is similar to an array, but the members are unique. Set itself is a constructor used to generate the Set data structure.
const a = new Set();
[1,2,3,3,4,1,2,3,2,2,1].forEach(b => a.add(b));
for(let i of a) {
console.log(i)
}
// 1 2 3 4
The Set function can accept an array (or other data of other iterable interfaces) as a parameter to initialize.
const set = new Set([1,2,3,4,5,4,3,2,1]);
[...set]
// [1, 2, 3, 4, 5]
No type conversion occurs when adding a value to the set, so 5 and '5' are two different values.
two objects are always unequal
let s = new Set();
s.add({}).add({});
s.size // 2
Properties and Methods of Set Instances
Instances of the set structure have the following methods:
- Set.propotype.constructor: constructor, the default is the Set function
- Set.prototype.size: returns the total number of members of the Set instance
The method of Set instance is divided into operation method and traversal method
Operation method:
- add(value): Add a value and return the Set structure itself.
- delete(value): Delete a value and return a Boolean value indicating success or failure.
- has(value): Returns a Boolean value, indicating whether the parameter is a Set member.
- clear(): clears all members, no return value.
let s = new Set();
s.add(1).add(2);
s.size // 2
s.delete(1) // true
s.has(1) // false
s.clear()
s.size // 0
Traverse operation:
- keys: Returns a iterator of key names.
- values: Returns a iterator for key values.
- entries: Returns a iterator of key-value pairs.
- forEach: use the callback function to traverse each member.
The order of Set traversal is the order of insertion
Since the Set structure has no key names, only key values. All keys methods behave exactly the same as values methods.
let set = new Set(['red', 'green', 'blue']);
for (let key of set.keys()) {
console.log(key)
};
// red green blue
for (let value of set.values()) {
console.log(value)
};
// red green blue
for (let item of set.entries()) {
console.log(item)
};
// ["red", "red"] ["green", "green"] ["blue", "blue"]
// for of 也可直接遍历Set
for (let item of set) {
console.log(item)
};
// red green blue
let set = new Set([1, 2, 3]);
set.forEach((value, key) => console.log(value * 2));
// 2 4 6
Convert the Set data structure to Array:
let set = new Set([1, 2, 3]);
// 方法一
Array.from(set);
// 方法二
[...set]
Applications traversed:
Extend operator and Set with deduplication
let arr = [1, 2, 3, 3, 4, 2, 1];
let set = [...new Set(arr)];
// [1, 2, 3, 4]
Using map and filter with the spread operator
let set = new Set([1, 2, 3]);
set = new Set([...set].map(a => a * 2));
// 2, 4, 6
intersection, union, difference
let a = new Set([1, 2, 3]);
let b = new Set([3, 4, 5]);
// 并集
let union = new Set([...a, ...b]);
// 1, 2, 3, 4, 5
// 交集
let intersect = new Set([...a].filter(x => b.has(x)));
// 3
// 差集
let intersect = new Set([...a].filter(x => !b.has(x)));
// 1, 2
If you want to change the original Set structure synchronously during the traversal operation, there are only two workarounds.
let set = new Set([1, 2, 3]);
// 方法一
set = new Set([...set].map(x => x * 2));
// 方法二
set = new Set(Array.from(set, val => val * 2));
WeakSet
meaning
WeakSet is similar to Set and is also a collection of unique values. But he has two differences from Set:
1. Members of WeakSet can only be objects, not other types of values
consr ws = new WeakSet();
ws.add(1);
// 报错
ws.add(Symnol());
// 报错
2. The objects in the WeakSet are all weak references, that is, the garbage collection mechanism does not consider the WeakSet's reference to the object. That is to say, if other objects do not refer to the object, the garbage collection mechanism will automatically reclaim the memory occupied by the object, regardless of whether the object still exists in the WeakSet.
grammar
WeakSet is a constructor that can use the new command to create a WeakSet data structure.
const ws = new WeakSet()
As a constructor, WeakSet accepts an array or array-like object as a parameter. Objects with iterable interface can also be used as parameters of WeakSet.
const a = [[1, 2], [3, 4]];
const ws = new WeakSet(a);
// WeakSet {[1, 2], [3, 4]}
const b = [3, 4];
const ws = new WeakSet(b);
// 报错,数组b的成员不是对象
The WeakSet structure has the following three methods:
- WeakSet.prototype.add(value): Add members to the WeakSet instance
- WeakSet.prototype.delete(value): Clear the specified member of the WeakSet instance
- WeakSet.prototype.has(value): Returns a Boolean value indicating whether a value is in the WeakSet instance
WeakSet has no size property, and there is no way to iterate over its members.
Map
Meaning and Basic Usage
JavaScript objects are essentially a collection of key-value pairs, but only strings can be used as keys. ES6 provides a Map data structure, which is similar to objects, but any type of value can be used as a key (including objects).
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
As a constructor, Map can also accept an array as a parameter, and the members of the array are arrays representing key-value pairs.
const map = new Map([
['name', '张三'],
['title', '提示']
]);
map.size // 2
map.has('name') // true
map.get('name') // "张三"
map.has('title') // true
map.get('title') // "提示"
Set and Map can also be used to generate new Maps. (Any data structure that has an iterator interface and each member is a two-element array can be used as a parameter of the Map constructor)
If multiple assignments are made to the same key, later values will overwrite earlier ones. Only references to the same object are considered the same key by the Map structure.
const map = new Map();
map.set(['a'], 555);
map.get(['a']); // undefined
Because the memory addresses of the two arrays are different, the get method cannot read the key and returns undefined.
Manipulation Methods for Instances and Properties
- size attribute: returns the total number of members of the Map structure
- set(key, value): Set the key value corresponding to the key, and then return the entire Map structure. If the key already has a value, the key value will be updated, otherwise, the key will be newly generated
- get(key): read the key value corresponding to the key, if the key cannot be found, return undefined
- has(key): Returns a Boolean value indicating whether a key is in the Map data structure
- delete(key): Delete a key and return true. Delete failed, return false
- clear(): Clear all members, no return value
traversal method
- keys method: returns a traverser of key names
- Values method: returns a traverser of key values
- entries method: returns a traverser of all members
- forEach method: traverse all members of the Map
The order of Map traversal is the order of insertion
You can use for of to traverse directly, which is equivalent to map.entries()
It can also be converted into an array using the extension operator, and the traversal and filtering can be realized through the map method and the filter method.
Interconversion with other data structures
Map to array
const myMap = new Map()
.set(true, 7)
.set({foo: 3}, ['abc']);
[...myMap]
// [ [ true, 7 ], [ { foo: 3 }, [ 'abc' ] ] ]
Array to Map
new Map([
[true, 7],
[{foo: 3}, ['abc']]
])
// Map {
// true => 7,
// Object {foo: 3} => ['abc']
// }
Map to object
function strMapToObj(strMap) {
let obj = Object.create(null);
for (let [k,v] of strMap) {
obj[k] = v;
}
return obj;
}
const myMap = new Map()
.set('yes', true)
.set('no', false);
strMapToObj(myMap)
// { yes: true, no: false }
Object to Map
function objToStrMap(obj) {
let strMap = new Map();
for (let k of Object.keys(obj)) {
strMap.set(k, obj[k]);
}
return strMap;
}
objToStrMap({yes: true, no: false})
// Map {"yes" => true, "no" => false}
Map to JSON
function strMapToJson(strMap) {
return JSON.stringify(strMapToObj(strMap));
}
let myMap = new Map().set('yes', true).set('no', false);
strMapToJson(myMap)
// '{"yes":true,"no":false}'
function mapToArrayJson(map) {
return JSON.stringify([...map]);
}
let myMap = new Map().set(true, 7).set({foo: 3}, ['abc']);
mapToArrayJson(myMap)
// '[[true,7],[{"foo":3},["abc"]]]'
JSON to Map
function jsonToStrMap(jsonStr) {
return objToStrMap(JSON.parse(jsonStr));
}
jsonToStrMap('{"yes": true, "no": false}')
// Map {'yes' => true, 'no' => false}
function jsonToMap(jsonStr) {
return new Map(JSON.parse(jsonStr));
}
jsonToMap('[[true,7],[{"foo":3},["abc"]]]')
// Map {true => 7, Object {foo: 3} => ['abc']}
WeakMap
meaning
WeakMap
Structs Map
are similar to structs and are also used to generate collections of key-value pairs.
// WeakMap 可以使用 set 方法添加成员
const wm1 = new WeakMap();
const key = {foo: 1};
wm1.set(key, 2);
wm1.get(key) // 2
// WeakMap 也可以接受一个数组,
// 作为构造函数的参数
const k1 = [1, 2, 3];
const k2 = [4, 5, 6];
const wm2 = new WeakMap([[k1, 'foo'], [k2, 'bar']]);
wm2.get(k2) // "bar"
WeakMap and Map have the following two differences
1. WeakMap
Only accept objects as keys ( null
except), and do not accept other types of values as keys.
const map = new WeakMap();
map.set(1, 2)
// TypeError: 1 is not an object!
map.set(Symbol(), 2)
// TypeError: Invalid value used as weak map key
map.set(null, 2)
// TypeError: Invalid value used as weak map key
2. WeakMap
The object pointed to by the key name is not included in the garbage collection mechanism. The objects referenced by its key name are all weak references, that is, the garbage collection mechanism does not take the reference into consideration. Therefore, as soon as other references to the referenced object are cleared, the garbage collection mechanism will free the memory occupied by the object. That is to say, once it is no longer needed, the key name object and the corresponding key-value pair in the WeakMap will disappear automatically, and there is no need to manually delete the reference.
WeakMap syntax
There are two differences between WeakMap and Map methods
First, there is no traversal operation and no size
attributes
Second, it cannot be cleared, that is, clear
the method is not supported.
WeakMap
Only four methods are available: get()
, set()
, has()
, delete()
.
const wm = new WeakMap();
// size、forEach、clear 方法都不存在
wm.size // undefined
wm.forEach // undefined
wm.clear // undefined