几乎每种编程语言中,都有集合结构。集合比较常见的实现方式是哈希表,这里使用 JavaScript 的 Object 进行封装。
集合通常是由一组无序的、不能重复的元素构成。
数学中常指的集合中的元素是可以重复的,但是计算机中集合的元素不能重复。
集合是特殊的数组。
ES6 中的 Set
就是一个集合类,这里我们重新封装一个 Set
类,了解集合的底层实现。
add(value)
向集合添加一个新的项。remove(value)
从集合移除一个值。has(value)
如果值在集合中,返回 true
,否则返回 false
。clear()
移除集合中的所有项。size()
返回集合所包含元素的数量。与数组的 length
属性类似。values()
返回一个包含集合中所有值的数组。// 集合结构的封装class Set {constructor() {this.items = {};}// has(value) 判断集合中是否存在 value 值,存在返回 true,否则返回 falsehas(value) {return this.items.hasOwnProperty(value);}// add(value) 往集合中添加 valueadd(value) {if (this.has(value)) return false;this.items[value] = value;return true;}// remove(value) 删除集合中指定的 valueremove(value) {// 如果集合不存在该 value,返回 falseif (!this.has(value)) return false;delete this.items[value];}// clear() 清空集合中所有 valueclear() {this.items = {};}// size() 获取集合中的 value 个数size() {return Object.keys(this.items).length;}// values() 获取集合中所有的 valuevalues() {return Object.keys(this.items);}}
const set = new Set();// add() 测试set.add("abc");set.add("abc");set.add("123");set.add("zxc");console.log(set); //--> {items: {123: "123", abc: "abc", zxc: "zxc"}}// has() 测试console.log(set.has("123")); //--> trueconsole.log(set.has("456")); //--> false// remove() 测试set.remove("abc");console.log(set); //--> {items: {123: "123", zxc: "zxc"}}// size() 测试console.log(set.size()); //--> 2// values() 测试console.log(set.values()); //--> ["123", "zxc"]// clear() 测试set.clear();console.log(set.values()); //--> []
// union() 求两个集合的并集union(otherSet) {// 1、创建一个新集合let unionSet = new Set();// 2、将当前集合(this)的所有 value,添加到新集合(unionSet)中for (let value of this.values()) {unionSet.add(value);}// 3、将 otherSet 集合的所有 value,添加到新集合(unionSet)中for (let value of otherSet.values()) {unionSet.add(value); // add() 已经有重复判断}return unionSet;}
// intersection() 求两个集合的交集intersection(otherSet) {// 1、创建一个新集合let intersectionSet = new Set();// 2、从当前集合中取出每一个 value,判断是否在 otherSet 集合中存在for (let value of this.values()) {if (otherSet.has(value)) {intersectionSet.add(value);}}return intersectionSet;}
// difference() 差集difference(otherSet) {// 1、创建一个新集合let differenceSet = new Set();// 2、从当前集合中取出每一个 value,判断是否在 otherSet 集合中存在,不存在的即为差集for (let value of this.values()) {if (!otherSet.has(value)) {differenceSet.add(value);}}return differenceSet;}
// subset() 子集subset(otherSet) {// 从当前集合中取出每一个 value,判断是否在 otherSet 集合中存在,有不存在的返回 false// 遍历完所有的,返回 truefor (let value of this.values()) {if (!otherSet.has(value)) {return false;}}return true;}
// 集合结构的封装class Set {constructor() {this.items = {};}// has(value) 判断集合中是否存在 value 值,存在返回 true,否则返回 falsehas(value) {return this.items.hasOwnProperty(value);}// add(value) 往集合中添加 valueadd(value) {if (this.has(value)) return false;this.items[value] = value;return true;}// remove(value) 删除集合中指定的 valueremove(value) {// 如果集合不存在该 value,返回 falseif (!this.has(value)) return false;delete this.items[value];}// clear() 清空集合中所有 valueclear() {this.items = {};}// size() 获取集合中的 value 个数size() {return Object.keys(this.items).length;}// values() 获取集合中所有的 valuevalues() {return Object.keys(this.items);}// ------- 集合间的操作 ------- //// union() 求两个集合的并集union(otherSet) {// 1、创建一个新集合let unionSet = new Set();// 2、将当前集合(this)的所有 value,添加到新集合(unionSet)中for (let value of this.values()) {unionSet.add(value);}// 3、将 otherSet 集合的所有 value,添加到新集合(unionSet)中for (let value of otherSet.values()) {unionSet.add(value); // add() 已经有重复判断}return unionSet;}// intersection() 求两个集合的交集intersection(otherSet) {// 1、创建一个新集合let intersectionSet = new Set();// 2、从当前集合中取出每一个 value,判断是否在 otherSet 集合中存在for (let value of this.values()) {if (otherSet.has(value)) {intersectionSet.add(value);}}return intersectionSet;}// difference() 差集difference(otherSet) {// 1、创建一个新集合let differenceSet = new Set();// 2、从当前集合中取出每一个 value,判断是否在 otherSet 集合中存在,不存在的即为差集for (let value of this.values()) {if (!otherSet.has(value)) {differenceSet.add(value);}}return differenceSet;}// subset() 子集subset(otherSet) {// 从当前集合中取出每一个 value,判断是否在 otherSet 集合中存在,有不存在的返回 false// 遍历完所有的,返回 truefor (let value of this.values()) {if (!otherSet.has(value)) {return false;}}return true;}}