JS数据结构(二)--集合

120 阅读2分钟

前言

本文主要讲解了 关于数据结构 集合 中的相关概念,关于集合已经在 Set 类中事实现了,之后有时间会更新关于 Set 相关文章;

定义
  • 集合是一种无序且唯一(不能重复)的项组成的
  • 集合有并集,交集,差集,子集等基本运算
  • 以[值,值]的形式存储元素
实现

方法

  • add(value):向集合添加一个新的项
  • remove(value):从集合移除一个值
  • has(value):如果值在集合中,返回true,否则返回false
  • clear():移除集合中的所有项
  • size():返回集合所包含的元素数量,与数组的length属性相似
  • values():返回一个集合中所有值的数组
  • union(setName):并集,返回包含两个集合所有元素的新集合(元素不重复)
  • intersection(setName):交集,返回包含两个集合中共有的元素的集合、
  • difference(setName):差集,返回包含所有存在本集合而不存在setName集合的元素的新集合
  • subset(setName):子集,验证setName是否是本集合的子集
 class SetFn {
  constructor(){
    this.items = {};
  }
  
  add(value) {
    if (!this.has(value)) {
      this.items[value] = value;
      return true;
    }
    return false;
  }
  delete(value) {
    if (this.has(value)) {
      delete this.items[value];
      return true;
    }
    return false;
  }
  has(value) {

    return Object.prototype.hasOwnProperty.call(this.items,value)
  }

  clear() {
    this.items = {};
  }

  size() {
    return Object.keys(this.items).length;
  }


  sizeLegacy() {
    let count = 0;
    for (let key in this.items) {
      if (this.items.hasOwnProperty(key))
        ++count;
    }
    return count;
  }

  values() {
    let values = [];
    for (let i = 0, keys = Object.keys(this.items); i < keys.length; i++) {
      values.push(this.items[keys[i]]);
    }
    return values;
  }
  valuesLegacy() {
    let values = [];
    for (let key in this.items) {
      if (this.items.hasOwnProperty(key)) {
        values.push(this.items[key]);
      }
    }
    return values;
  }
  getitems() {
    return this.items;
  }
  
  union(otherSet) {
    let unionSet = new SetFn();
    let values = this.values();
    for (let i = 0; i < values.length; i++) {
      unionSet.add(values[i]);
    }
    values = otherSet.values();
    for (let i = 0; i < values.length; i++) {
      unionSet.add(values[i]);
    }
    return unionSet;
  }
  intersection(otherSet) {
    let intersectionSet = new SetFn();
    let values = this.values();
    for (let i = 0; i < values.length; i++) {
      if (otherSet.has(values[i])) {
        intersectionSet.add(values[i]);
      }
    }
    return intersectionSet;
  }
  difference(otherSet) {
    let differenceSet = new SetFn();
    let values = this.values();
    for (let i = 0; i < values.length; i++) {
      if (!otherSet.has(values[i])) {
        differenceSet.add(values[i]);
      }
    }
    return differenceSet;
  }
  subset(otherSet) {
    if (this.size() > otherSet.size()) {
      return false;
    } else {
      let values = this.values();
      for (let i = 0; i < values.length; i++) {
        if (!otherSet.has(values[i])) {
          return false;
        }
      }
      return true;
    }
  }
}


const set = new SetFn();

set.add(1);
console.log(set.values()) //[1]
console.log(set.has(1)) // true
console.log(set.size()); // 1

set.add(2);
console.log(set.values()) //[1,2]
console.log(set.has(2)) //// true
console.log(set.size()); // 2

set.delete(1);
console.log(set.values()) //[2]



//并集

const setUnionA = new SetFn()
setUnionA.add(1);
setUnionA.add(2);
setUnionA.add(3);


const setUnionB = new SetFn()

setUnionA.add(3);
setUnionA.add(4);
setUnionA.add(5);

const unionAB = setUnionA.union(setUnionB)
console.log(unionAB.values()) //[ 1, 2, 3, 4, 5 ]

// 交集 

const setIntersectionA = new SetFn()
setIntersectionA.add(1);
setIntersectionA.add(2);
setIntersectionA.add(3);


const setIntersectionB = new SetFn()

setIntersectionB.add(2);
setIntersectionB.add(3);
setIntersectionB.add(4);

const setIntersectionAB = setIntersectionA.intersection(setIntersectionB)
console.log(setIntersectionAB.values()) //[ 2, 3 ]


//差集

const setDifferencaA = new SetFn()
setDifferencaA.add(1);
setDifferencaA.add(2);
setDifferencaA.add(3);


const setDifferencaB = new SetFn()

setDifferencaB.add(2);
setDifferencaB.add(3);
setDifferencaB.add(4);

const setDifferencaAB = setDifferencaA.difference(setDifferencaB)
console.log(setDifferencaAB.values()) //[ 1]


//子集

const setIsSubsetOfA = new SetFn()
setIsSubsetOfA.add(1);
setIsSubsetOfA.add(2);

const setIsSubsetOfB = new SetFn()

setIsSubsetOfB.add(1);
setIsSubsetOfB.add(2);
setIsSubsetOfB.add(3);

const setIsSubsetOfC = new SetFn()

setIsSubsetOfB.add(2);
setIsSubsetOfB.add(3);
setIsSubsetOfB.add(4);


console.log(setIsSubsetOfA.isSubsetOf(setIsSubsetOfB)) // true
console.log(setIsSubsetOfA.isSubsetOf(setIsSubsetOfC)) // false

Set 类

关于 ES2015 的Set的values 方法 返回Inerator ,而不是值构成的数组

使用扩展运算符 实现集合运算

使用原生Set 类创建

 const setA = new Set()
  
 setA.add(1);
 setA.add(2);
 setA.add(3);

 
 const setB = new Set()
  
 setB.add(2);
 setB.add(3);
 setB.add(4);

  • 并集
    console.log(new Set([...setA,...setB]))
  • 交集
    console.log(new Set([...setA].filter(x=> setB.has(x) )))
  • 差集
    console.log(new Set([...setA].filter(x=> !setB.has(x) )))

最后

希望疫情这一场无声的战争 早日过去 (前端界的一枚小学生)