- 昨天实现的集合有一些bug,这次重写了代码。
集合数据结构
- 集合是由一组无序且唯一(即不重复)的项组成
- 空集:空集是不包含任何元素的集合
- 可以把集合想象成一个既没有重复元素,也没有顺序概念的数组
- 集合在计算机领域中的运用
- 集合在计算机科学中的主要应用之一是数据库
- 集合被用于数据库查询的设计和处理
- 当我们执行数据库的查询语句时,使用的就是集合运算,并且数据库也会返回一个数据集合
- 集合的运算
- 并集:对于给定的两个集合,返回一个包含两个集合中所有元素的新集合
- 交集:对于给定的两个集合,返回一个包含两个集合中共有的元素的新集合
- 差集:对于给定的两个集合,返回一个包含所有存在于第一个集合但不存在于第二个集合中的元素组成的新集合
- 子集:验证一个给定的集合中的元素是否都存在于另一个集合中
使用对象实现集合
-
将参数转换为字符串
/*将传入的参数转换为字符串*/ const toStr = (param) => { if (param === null) { return 'NULL'; } else if (param === undefined) { return 'UNDEFINED'; } else if (typeof param === 'number' || param instanceof Number) { return `${param}`; } else if (typeof param === 'string' || param instanceof String) { return `${param}`; } else if (typeof param === 'symbol') { return param; } else { return JSON.stringify(param); } };
-
方法
- add(element):向集合中添加一个新元素
- delete(element):从集合中删除一个元素
- has(element):判断元素是否存在于集合中,存在返回true,不存在返回false
- clear():删除集合中所有的元素
- size():返回集合中所有元素的数量。它与数组的length属性类似
- values():返回由集合中所有元素构成的数组
- union(otherSet):返回当前集合和另一个集合的并集
- intersection(otherSet):返回当前集合和另一个集合的交集
- difference(otherSet):返回当前集合和另一个集合的差集
- isSubsetOf(otherSet):判断当前集合是否是另一个集合的子集
-
代码
/*创建集合的类*/ class Set { constructor() { this.items = {}; // 存储集合元素的对象 } // add(element):向集合中添加一个新元素 add(element) { if (this.has(element)) { // element在集合中 return false; } const key = toStr(element); this.items[key] = element; return true; } // delete(element):从集合中删除一个元素 delete(element) { if (this.has(element)) { // element在集合中 const key = toStr(element); delete this.items[key]; return true; } return false; } // has(element):判断元素是否存在于集合中,存在返回true,不存在返回false has(element) { const key = toStr(element); return Object.prototype.hasOwnProperty.call(this.items, key); } // clear():删除集合中所有的元素 clear() { this.items = {}; } // size():返回集合中所有元素的数量。它与数组的length属性类似 size() { return Object.keys(this.items).length; } // values():返回由集合中所有元素构成的数组 values() { return Object.values(this.items); } // union(otherSet):返回当前集合和另一个集合的并集 union(otherSet) { const newSet = new Set(); this.values() .concat(otherSet.values()) .forEach((v) => newSet.add(v)); return newSet; } // intersection(otherSet):返回当前集合和另一个集合的交集 intersection(otherSet) { const newSet = new Set(); // 找到元素最多的集合 let bigSet = this; let smallSet = otherSet; if (bigSet.values().length < smallSet.values().length) { // 如果bigSet中的元素数量小于smallSet中元素的数量 bigSet = otherSet; smallSet = this; } smallSet.values() .filter((v) => bigSet.has(v)) .forEach((v) => newSet.add(v)); return newSet; } // difference(otherSet):返回当前集合和另一个集合的差集 difference(otherSet) { const newSet = new Set(); this.values() .filter((v) => !otherSet.has(v)) .forEach((v) => newSet.add(v)); return newSet; } // isSubsetOf(otherSet):判断当前集合是否是另一个集合的子集 isSubsetOf(otherSet) { if (this.size() > otherSet.size()) { //如果当前集合中的元素大于另一个集合中的元素 return false; } return this.values().every((v) => otherSet.has(v)); } }
-
集合的使用
const set1 = new Set(); set1.add(1); set1.add({}); set1.add(undefined); set1.add(undefined); set1.add(null); set1.add(null); set1.add({a:'李四'}); const set2 = new Set(); set2.add(1); set2.add(2); set2.add([1]); set2.add(['a','b','c']); set2.add(undefined); console.log(set1.values()); console.log(set1.union(set2).values()); console.log(set1.intersection(set2).values()); console.log(set1.difference(set2).values()); console.log(set1.isSubsetOf(set2)); // 结果 // [ 1, {}, undefined, null, { a: '李四' } ] // [ 1, 2, {}, undefined, null, { a: '李四' }, [ 1 ], [ 'a', 'b', 'c' ] ] // [ 1, undefined ] // [ {}, null, { a: '李四' } ] // false