[6a3a178] | 1 | /*
|
---|
| 2 | MIT License http://www.opensource.org/licenses/mit-license.php
|
---|
| 3 | Author Tobias Koppers @sokra
|
---|
| 4 | */
|
---|
| 5 |
|
---|
| 6 | "use strict";
|
---|
| 7 |
|
---|
| 8 | /**
|
---|
| 9 | * intersect creates Set containing the intersection of elements between all sets
|
---|
| 10 | * @template T
|
---|
| 11 | * @param {Set<T>[]} sets an array of sets being checked for shared elements
|
---|
| 12 | * @returns {Set<T>} returns a new Set containing the intersecting items
|
---|
| 13 | */
|
---|
| 14 | const intersect = sets => {
|
---|
| 15 | if (sets.length === 0) return new Set();
|
---|
| 16 | if (sets.length === 1) return new Set(sets[0]);
|
---|
| 17 | let minSize = Infinity;
|
---|
| 18 | let minIndex = -1;
|
---|
| 19 | for (let i = 0; i < sets.length; i++) {
|
---|
| 20 | const size = sets[i].size;
|
---|
| 21 | if (size < minSize) {
|
---|
| 22 | minIndex = i;
|
---|
| 23 | minSize = size;
|
---|
| 24 | }
|
---|
| 25 | }
|
---|
| 26 | const current = new Set(sets[minIndex]);
|
---|
| 27 | for (let i = 0; i < sets.length; i++) {
|
---|
| 28 | if (i === minIndex) continue;
|
---|
| 29 | const set = sets[i];
|
---|
| 30 | for (const item of current) {
|
---|
| 31 | if (!set.has(item)) {
|
---|
| 32 | current.delete(item);
|
---|
| 33 | }
|
---|
| 34 | }
|
---|
| 35 | }
|
---|
| 36 | return current;
|
---|
| 37 | };
|
---|
| 38 |
|
---|
| 39 | /**
|
---|
| 40 | * Checks if a set is the subset of another set
|
---|
| 41 | * @template T
|
---|
| 42 | * @param {Set<T>} bigSet a Set which contains the original elements to compare against
|
---|
| 43 | * @param {Set<T>} smallSet the set whose elements might be contained inside of bigSet
|
---|
| 44 | * @returns {boolean} returns true if smallSet contains all elements inside of the bigSet
|
---|
| 45 | */
|
---|
| 46 | const isSubset = (bigSet, smallSet) => {
|
---|
| 47 | if (bigSet.size < smallSet.size) return false;
|
---|
| 48 | for (const item of smallSet) {
|
---|
| 49 | if (!bigSet.has(item)) return false;
|
---|
| 50 | }
|
---|
| 51 | return true;
|
---|
| 52 | };
|
---|
| 53 |
|
---|
| 54 | /**
|
---|
| 55 | * @template T
|
---|
| 56 | * @param {Set<T>} set a set
|
---|
| 57 | * @param {function(T): boolean} fn selector function
|
---|
| 58 | * @returns {T | undefined} found item
|
---|
| 59 | */
|
---|
| 60 | const find = (set, fn) => {
|
---|
| 61 | for (const item of set) {
|
---|
| 62 | if (fn(item)) return item;
|
---|
| 63 | }
|
---|
| 64 | };
|
---|
| 65 |
|
---|
| 66 | /**
|
---|
| 67 | * @template T
|
---|
| 68 | * @param {Set<T>} set a set
|
---|
| 69 | * @returns {T | undefined} first item
|
---|
| 70 | */
|
---|
| 71 | const first = set => {
|
---|
| 72 | const entry = set.values().next();
|
---|
| 73 | return entry.done ? undefined : entry.value;
|
---|
| 74 | };
|
---|
| 75 |
|
---|
| 76 | /**
|
---|
| 77 | * @template T
|
---|
| 78 | * @param {Set<T>} a first
|
---|
| 79 | * @param {Set<T>} b second
|
---|
| 80 | * @returns {Set<T>} combined set, may be identical to a or b
|
---|
| 81 | */
|
---|
| 82 | const combine = (a, b) => {
|
---|
| 83 | if (b.size === 0) return a;
|
---|
| 84 | if (a.size === 0) return b;
|
---|
| 85 | const set = new Set(a);
|
---|
| 86 | for (const item of b) set.add(item);
|
---|
| 87 | return set;
|
---|
| 88 | };
|
---|
| 89 |
|
---|
| 90 | exports.intersect = intersect;
|
---|
| 91 | exports.isSubset = isSubset;
|
---|
| 92 | exports.find = find;
|
---|
| 93 | exports.first = first;
|
---|
| 94 | exports.combine = combine;
|
---|