[This is the 30th day of my participation in the Gengwen Challenge. For details, see “Gengwen Challenge”]

In many cases, you need to compare multiple lists to find out if they have or do not intersect, sets of differences, and so on. There is a data type in Javascript that works well for these requirements: Set.

A Set object is like an array, but contains only unique items. A Set object is a collection of values whose elements can be iterated over in the order in which they were inserted. The elements in a Set occur only once, that is, the elements in a Set are unique. Is a great way to merge arrays and deduplicate them, and is briefly mentioned in the article ES6 Features you can use in Vue development.

Codepen. IO /quintiontan…

What is theSet

A Set object is a collection of values whose elements can be iterated over in the order in which they were inserted. Elements appear only once, that is, a Set is a collection of unique values stored in no particular order. Unlike other collection types such as stack, queue, and array, a Set can be used for list comparisons and is used to detect the presence of an item in a collection.

A Set is an abstract data type defined by its behavior, similar to stack and queue data structures. This is similar to a Map because of the key-key feature. For details, see ECMAScript 6 Map Mapping.

Javascript Set

Set in Javascript is very basic and simple, and does not provide the common Set manipulation capabilities that other languages do. It uses a unique algorithm (not based on strict equality ===) to detect whether elements are the same.

This means that storing undefined, null, and NaN in the collection will only be done once, even if it’s a NaN! == NaN, which is usually applied to the storage of object types.

const setTest = new Set([0, -0, Infinity,null, undefined, null, NaN, NaN, Infinity,null]);
console.log(setTest);  // Set { 0, Infinity, null, undefined, NaN }
Copy the code

From the above results, the following conclusions can be drawn:

  • althoughNaNNaNIt’s not equal, but it’s inSetThere’s only going to be one in the set
  • undefinedInfinitySetThere’s only going to be one in the set

The use of the basic Set is not covered in this article, but is available on the Mozilla web site.

When to useSet

Set is used to compare and determine whether or not a particular list is equal. The following describes how it works:

  • Gets the union of two setsunion
  • Gets the difference set of two setsdifference
  • Gets the intersection of two setsintersection
  • Gets the set of symmetric differences between two setsintersectionDifference
  • Determine whether two sets are subsetsisSubset
  • Determine whether two sets are supersetsisSuperset

The following three occasions to introduce the Set related operations.

Setoperation

In mathematics, there are operations that can be performed whenever a Set is talked about. In fact, a Set is a computer implementation of a mathematical finite Set.

To better illustrate the Set operation in the code, the sample code extends the Javascript Set to inherit its properties and methods, and adds additional methods to it.

For the example code, there is only a simple way to check whether it is a valid collection that is not empty.

Class SetHelper extends Set {/** * Extends Set * @param {*} Set * @returns */ _isValid = (Set) => {return Set && Set instanceof Set && set.size > 0; }; }Copy the code

And setunion

The union operation merges multiple sets and returns the combined result. The implementation returns a new set by combining the current set with the given set into an array and creating it.

union(set) { if (! this._isValid(set)) return new SetHelper(); return new SetHelper([...this, ...set]); }Copy the code

Difference setdifference

The difference operation returns a new set containing only elements in one set that are not in the other, the mathematical concept of difference sets.

difference(set) { if (! this._isValid(set)) return new SetHelper(); const differenceSet = new SetHelper(); this.forEach((item) => { ! set.has(item) && differenceSet.add(item); }); return differenceSet; }Copy the code

intersectionintersection

The intersection operation returns a new collection containing only elements that are shared by the two collections. The implementation iterates over the smaller set (avoiding unnecessary checks) and checks for each item in the larger set and adds it to the intersection set, returning the intersection when the iterating is complete.

intersection(set) { const intersectionSet = new SetHelper(); if (! this._isValid(set)) return intersectionSet; const [smallerSet, biggerSet] = set.size <= this.size ? [set, this] : [this, set]; smallerSet.forEach((item) => { biggerSet.has(item) && intersectionSet.add(item); }); return intersectionSet; }Copy the code

Symmetric difference setintersectionDifference

The intersectionDifference operation returns a new collection containing all elements for which the two collections do not intersect.

intersectionDifference(set) { if (! this._isValid(set)) return new SetHelper(); return new SetHelper([ ...this.difference(set), ...set.difference(this), ]); }Copy the code

A subset ofsubset

The isSubset operation determines whether two sets are subset related (when all the items of one set are contained in the other set). The implementation first checks the size of the two sets; if one set is larger, it cannot be a subset of the other, and then for each item, it checks whether it exists in the other.

isSubset(set) { if (! this._isValidSet(set)) return false; return ( this.size <= set.size && [...this].every((item) => set.has(item)) ); }Copy the code

supersetsuperset

The isSuperset operation determines whether two sets are superset. A superset is the inverse of a subset. A set is a superset when it contains all the items of another set of smaller or equal size.

isSuperset(set) { if (! this._isValidSet(set)) return false; return ( this.size >= set.size && [...set].every((item) => this.has(item)) ); }Copy the code

staticSet

A static Set is a collection that always contains the elements it initialized. Elements cannot be added, removed, or cleared. A Javascript Set is not static. It can always be created to expose methods that modify the Set, such as add or delete. To prevent the Set from being modified, you can create a new Set and reset the methods that modified it.

class StaticSet extends SetHelper { constructor(items) { super(items); this.add = undefined; this.delete = undefined; this.clear = undefined; }}Copy the code

use

We can now operate on both sets using the methods defined above, as follows:

const setA = new StaticSet(new Set([1, 2, 3, 4])); const setB = new StaticSet(new Set([3, 4, 5, 6])); console.log([...setA.union(setB)]); // [ 1, 2, 3, 4, 5, 6 ] console.log([...setA.difference(setB)]); // [ 1, 2 ] console.log([...setA.intersection(setB)]); // [ 3, 4 ] console.log([...setB.intersectionDifference(setA)]); // [5, 6, 1, 2]Copy the code

conclusion

Set is not limited to all of these operations. It has been described before that it can be used to merge arrays and deduplicate them. Since it is easy to convert sets to arrays, it is preferable to use sets when using arrays because they are less memory intensive than arrays.