一种无序且唯一的数据结构
es6中有集合Set
集合的常见操作:去重、判断某元素是否在集合中、求交集
1. 定义
集合是由一组无序且唯一(即不能重复)的项组成的
2. 具体操作
创建
1 2 3 4 5
| class Set { constructor() { this.items = {}; } }
|
方法
has(element):如果元素在集合中,返回true,否则返回false
1 2 3
| has(element) { return element in items; }
|
1 2 3
| has(element) { return Object.prototype.hasOwnProperty.call(this.item, element); }
|
add(element):向集合添加一个新元素
1 2 3 4 5 6 7
| add(element) { if(!this.has(element)) { this.items[element] = element; return true; } return false; }
|
delete(element):从集合移除一个元素
1 2 3 4 5 6 7
| detele(element) { if(this.has(element)) { detele this.items[element]; return true; } return false; }
|
clear():移除集合中的所有元素
1 2 3
| clear() { this.items = {}; }
|
size():返回集合所包含元素的数量。它与数组的length 属性类似
方法一:和其他数据结构一样,直接使用length
方法二:
1 2 3
| size() { return Object.keys(this.items).length; }
|
方法三:
1 2 3 4 5 6 7 8 9
| sizeLegacy() { let count = 0; for(let key in this.items) { if(this.items.hasOwnProperty(key)){ count++; } } return count; }
|
values():返回一个包含集合中所有值(元素)的数组
1 2 3
| values() { return Object.values(this.items); }
|
but Object.values()
是ECMAScript 2017添加的,适用于现代浏览器中,等价于:
1 2 3 4 5 6 7 8 9
| valuesLegacy() { let values = []; for(let key in this.items) { if(this.items.hasOwnProperty(key)) { values.push(key); } } return values; }
|
3. 使用
1 2 3 4 5 6 7 8 9 10 11 12 13
| const set = new Set(); set.add(1); console.log(set.values()); console.log(set.has(1)); console.log(set.size()); set.add(2); console.log(set.values()); console.log(set.has(2)); console.log(set.size()); set.delete(1); console.log(set.values()); set.delete(2); console.log(set.values());
|
1 2 3
| const arr = [1,1,2,2]; const arr2 = [...new Set(arr)];
|
4. 集合的运算
并集
1 2 3 4 5 6
| union(otherSet) { const unionSet = new Set(); this.values().forEach(value => unionSet.add(value)); otherSet.values().forEach(value => unionSet.add(value)); return unionSet; }
|
交集
1 2 3 4 5 6 7 8 9 10
| intersection(otherSet) { const intersectionSet = new Set(); const values = this.values(); for(let i = 0; i < values.length; i++) { if(otherSet.has(values[i])) { intersectionSet.add(values[i]); } } return intersectionSet; }
|
优化一下,迭代AB集合中元素较少的那个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| intersection(otherSet) { const intersectionSet = new Set(); const values = this.values(); const otherValues = otherSet.values(); let biggerSet = values; let smallerSet = otherValues; if (otherValues.length - values.length > 0) { biggerSet = otherValues; smallerSet = values; } smallerSet.forEach(value => { if (biggerSet.includes(value)) { intersectionSet.add(value); } }); return intersectionSet; }
|
差集
1 2 3 4 5 6 7 8 9
| difference(otherSet) { const differenceSet = new Set(); this.values().forEach(value => { if(!otherSet.has(value)) { differenceSet.add(value); } }); return differenceSet; }
|
子集
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| isSubsetOf(otherSet) { if(this.size() > otherSet.size()) { return false; } let isSubset = true; this.values().every(value => { if(!otherSet.has(value)){ isSubset = false; return false; } return true; }); return isSubset; }
|
5. 前端与集合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| let mySet = new Set();
let o = {a:1, b:2}; mySet.add(o) mySet.add({a:1, b:2}); mySet.add('text');
const has = mySet.has(o);
mySet.delete(o)
for(let item of mySet.keys()) console.log(item); for(let item of mySet.value()) console.log(item); for(let [key, value] of mySet.keys()) console.log(key, value);
const myArr =[...mySet]; const myArr = Array.from(mySet);
const mySet2 = new Set([1,2,3,4]); const intersection = new Set([..mySet].filter(x => mySet2.has(x))); const difference = new Set([..mySet].filter(x => !mySet2.has(x)));
|