JavaScript數據結構與算法(五)集合

集合是由一組無序且惟一(不能重複)的項組成的,與咱們高中數學學的集合一樣具備有限性,
這種數據結構大多數用來存儲惟一元素。數據庫

集合

建立集合類

class Set {
  constructor() {
    this.items = {};
  }

檢驗某個元素是否存在集合中。

has(element) {
    return Object.prototype.hasOwnProperty.call(this.items, element);
  }

添加元素

add(element) {
    if (!this.has(element)) {
      this.items[element] = element;//把鍵和值保存,有利於查找該元素
      return true;
    }
    return false;
  }

刪除和清空操做

delete(element) {
    if (this.has(element)) {
      delete this.items[element];
      return true;
    }
    return false;
  };
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;
    };
  }
*/

返回對象全部屬性值的數組

valuesLegacy(){
    let values = [];
    for(let key in this.items){
      if(this.items.hasOwnProperty(key)){
        values.push(key);
      };
    };
    return values;
  }
//另外一種寫法,只適用於現代瀏覽器
values() {
    return Object.values(this.items);
  }

以上就是集合數據結構的建立和成員函數的添加。而集合最主要的是它的運算,在計算機領域中應用最多的是數據庫,發送一條SQL查詢命令時,使用的是集合運算,返回的也是數據集合。接下來介紹相對常見的集合運算(如下代碼引用ES6語法)數組

集合運算

並集

union(otherSet) {
    const unionSet = new Set();
    this.values().forEach(value => unionSet.add(value));
    otherSet.values().forEach(value => unionSet.add(value));
    return unionSet;
  }

交集

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;
  }

差集

difference(otherSet) {
    const differenceSet = new Set();
    this.values().forEach(value => {
      if (!otherSet.has(value)) {
        differenceSet.add(value);
      }
    });
    return differenceSet;
  }

判斷當前集合是否是被檢測的集合的子集

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;
  }

以上是咱們實現的集合運算,可是ES2015原聲的Set並無這些功能,若是有須要的話,咱們也能夠模擬。瀏覽器

模擬運算

模擬並集運算

const union = (set1, set2) => {
  const unionAb = new Set();
  set1.forEach(value => unionAb.add(value));
  set2.forEach(value => unionAb.add(value));
  return unionAb;
};
//第二種:使用拓展運算符
new Set([...setA, ...setB]);

模擬交集運算

const intersection = (set1, set2) => {
  const intersectionSet = new Set();
  set1.forEach(value => {
    if (set2.has(value)) {
      intersectionSet.add(value);
    }
  });
  return intersectionSet;
};
//第二種:使用拓展運算符
new Set([...setA].filter(x => setB.has(x)))

模擬差集運算

const difference = (set1, set2) => {
  const differenceSet = new Set();
  set1.forEach(value => {
    if (!set2.has(value)) {
      differenceSet.add(value);
    }
  });
  return differenceSet;
};
//第二種:使用拓展運算符
new Set([...setA].filter(x => !setB.has(x)))
相關文章
相關標籤/搜索