A Set is a special Set whose value is never repeated
Use arrays every day. Have you ever had a Moment where you were worried about inserting a duplicate value? Use the Set Set! Sets have special data structures that ensure that inserted values are never repeated.
Set collection base API
- through
Set.prototype.constructor
The constructor creates a Set instance
/* * instantiate only: call constructor, no arguments */
let empty_set = new Set(a)/* * Instantiates and initializes: Pass in any iterate object and convert it to a Set */
let transfer_set4arr = new Set([1.2.3])
// Return Set(3) {1, 2, 3}
let transfer_set4string = new Set("huilin")
Set(5) {"h", "u", "I ", "l", "n"}
let transfer_set4set = new Set(new Set([5.6]))
// Set(2) {5, 6}
Copy the code
- access
Set.prototype.size
Property that returns the number of elements in the collection
console.log(empty_set.size) / / 0
console.log(transfer_set4arr.size) / / 3
Copy the code
- call
Set.prototype.has(value)
Method to determine whether the element exists
Set.has() performs better than array.includes () because it is optimized specifically for member tests
console.log(empty_set.has(1)) // false
console.log(transfer_set4arr.has('h')) // true
Copy the code
A judgment about unique values
- The Set collection is used to ensure uniqueness of values
Object.is(value1,value2)
Judge, not pass===(identity symbol)
Symbol, because identity will cast the variables on both sides. - For example, the values of both variables are
NaN
Or,0
and0
Is not equal with JS, butObject.is()
Is considered to be the same and therefore cannot be stored in the Set.
To learn more about object.is (), go to developer.mozilla.org/zh-CN/docs/…
let n1 = NaN
let n2 = NaN
console.log(n1 === n2)
// The identity symbol determines that the two are inconsistent, and prints false
console.log(Object.is(n1,n2))
// But object.is () checks that the two are the same and prints false
// The Set does not allow two nans to be put into the Set
let set = new Set()
set.add(n1).add(n2)
console.log(set.size)
// size: 1
Copy the code
- In the face of complex data types, the judgment is mainly based on the reference of the object. Inconsistent references, even if the data structure is consistent, are considered only different and therefore can be stored in the Set.
let same_value_set = new Set(a);// Store an object first
same_value_set.add({num: 0});
// Store a new object with a consistent structure
let obj = {num: 0};
same_value_set.add(obj);
// Can be stored successfully
console.log(same_value_set.size); / / 2
Copy the code
- call
Set.prototype.add(value)
Method to append data to the collection
The add() method can append any type of data, either as raw values or as object references
let set1 = new Set(a)Since the add() method always returns a reference to the current instance, the chain call is made
set1.add(1).add(2).add(3)
console.log(set1) // Set(3) {1, 2, 3}
// Note: When add() is passed to an array, Set inserts the array instance into the collection, not into the elements of the array
set1.add([4.5])
console.log(set1) // Set(4) {1, 2, 3, [4, 5]}
Copy the code
- call
Set.prototype.delete(value)
Method to remove an element from the collection
The delete() method returns whether the removal was successful, as does the.has() method
let success = set1.delete(1)
console.log(success)
// true
Copy the code
- call
Set.prototype.clear()
Method to empty the collection
let num_set = new Set([1.6.3])
console.log(num_set)
// Set(3) { 1, 6, 3 }
set1.clear()
console.log(num_set)
// Set(0) {}
Copy the code
Three ways to traverse a Set
- Since a collection has no subscript/index, it is often considered an “unordered collection”. But JavaScript remembers the order in which the elements were inserted, so it iterates over the elements in that order.
- Walk directly through the Set Set
let set = new Set([1.2.3.4.5])
for(let item of set){
console.log(item)
}
// Outputs: 1, 2, 3, 4, 5
Copy the code
- Create iterators for traversal
/* * There are three ways to create iterators * set.prototype.entries () * set.prototype.keys () * set.prototype.values () */
// The Set contains only values and no keys, but to make it look like iterating through a Map, set.entries () creates new iterators with equal keys and values, i.e. [value,value]
for(let [key,value] of set.entries()){
console.log(value)
}
// Outputs: 1, 2, 3, 4, 5
Set.keys() creates a new Iterator and returns each value
for(let key of set.keys()){
console.log(key)
}
// Outputs: 1, 2, 3, 4, 5
Set.values() and set.keys () return the value of each item
for(let value of set.values()){
console.log(value)
}
// Outputs: 1, 2, 3, 4, 5
Copy the code
- call
Set.prototype.forEach(callbackFn)
Methods through
// forEach(callbackFn) calls callbackFn in insertion order, fetching each value
set.forEach(item= > {
console.log(item)
})
// Outputs: 1, 2, 3, 4, 5
Copy the code
Set case practice
Conversion between Set and Array
/* * Set to Array */
let set1 = new Set([1.2.3])
/ / Array. The from () method
let arr1 = Array.from(set1)
// Extend the operator
let arr2 = [...set1]
/* * Array to Set */
// Use the Set constructor
let set = new Set(array)
Copy the code
Deduplication of a single array
let set = new Set([1.2.4.4.2.5])
console.log(set)
// Set(4) { 1, 2, 4, 5 }
Copy the code
Multiple arrays are merged to deduplicate
let arr1 = [1.2.4]
let arr2 = [1.5.6]
// By using the property of the Set, the elements of the Set are unique
let result = new Set([...set1, ...set2])
console.log(result)
// Set(5) { 1, 2, 4, 5, 6 }
Copy the code
Get the intersection (repeating elements)
let set1 = new Set([1.2.4])
let set2 = new Set([1.5.6])
// return the element that exists in both set1 and set2
let result = new Set([...set1].filter(x= > set2.has(x)))
console.log(result)
// Set(1) { 1 }
Copy the code
Determine if there are overlaps (duplicate elements)
let set1 = new Set([1.2.4])
let set2 = new Set([1.5.6])
function isMixed(set, subset) {
for (let elem of subset) {
if (set.has(elem)) {
return true; }}return false;
}
console.log(isMixed(set1, set2))
// true
Copy the code
Get the difference set: only repeats are returned
let set1 = new Set([1.2.4])
let set2 = new Set([1.5.6])
function difference(setA, setB) {
let result = new Set(a)for (let elem of setB) {
if(setA.has(elem)){
result.add(elem)
}
}
return result;
}
console.log(difference(set1, set2))
Copy the code
Where is WeakSet “weak”?
In addition to the Set Set, ES6 also provides WeakSet and WeakMap. The collection is called Weak, but what makes it Weak?
Weak function
- WeakSet does not allow the insertion of original values, only supports the reference of objects;
let val1 = {id: 1},
val2 = {id: 2}
let ws = new WeakSet(a)// Like Set, WeakSet value is not repeated, and add() also returns Set instance, so chain operation is possible
ws.add(val1).add(val1).add(val2)
// The underlying data types are not allowed to be inserted
ws.add(3)
TypeError: Invalid value used in WeakSet TypeError: Invalid value used in WeakSet
// But you can wrap it as an object before you insert it
let val3 = new Number(3)
ws.add(val3)
console.log(ws.has(val3))
// Output: true
Copy the code
- WeakSet is only implemented
add()
,has()
,delete()
Three operation methods; - WeakSet does not allow traversal and does not have size or length attributes;
A weak reference
To talk about weak references, let’s look at what a strong reference is:
// Declare an object
let handsome = {
name: 'huilin'.age: 30
}
// Put an array
let arr = [1, handsome, 2]
console.log('release before arr length', arr.length) / / 3
/ / in the Map
let user = {
oid: 10001.classify: 'Chinese'.staffReference: handsome
}
console.log('release before map length'.Object.keys(user).length) / / 3
console.log(The '-')
// Suddenly set the object to null
handsome = null
// In a strongly referenced container, the object still exists and has not been collected
console.log('release after arr length', arr.length) / / 3
console.log(arr[1]) // { name: 'huilin', age: 30 }
console.log('release after map length'.Object.keys(user).length) / / 3
console.log(user.staffReference) // { name: 'huilin', age: 30 }
Copy the code
From the test code, the referenced object is never reclaimed unless the container is destroyed. Weak references, on the other hand, mean that the container is expected to scale automatically based on the element, and if the object is null, the reference in the container is also recycled.
let obj1 = {
name: 'huilin'.age: 30
}
let obj2 = {
name: 'cc'.age: 29
}
let ws1 = new WeakSet()
ws1.add(obj1).add(obj2)
console.log(ws1.has(obj1)) // true
// Manipulate elements from containers
ws1.delete(obj1)
console.log(ws1.has(obj1)) // false
// If the object is set to null, it is automatically reclaimed
obj2 = null
console.log(ws1.has(obj2)) // false
Copy the code
Reference
- zh.javascript.info/map-set
- Es6.ruanyifeng.com/#docs/set-m…