JavaScript實現集合與字典

  • 2020 年 3 月 12 日
  • 筆記

JavaScript實現集合與字典

一、集合結構

1.1.簡介

集合比較常見的實現方式是哈希表,這裡使用JavaScript的Object類進行封裝。

集合通常是由一組無序的不能重複的元素構成。

  • 數學中常指的集合中的元素是可以重複的,但是計算機中集合的元素不能重複。

集合是特殊的數組:

  • 特殊之處在於裏面的元素沒有順序也不能重複
  • 沒有順序意味着不能通過下標值進行訪問,不能重複意味着相同的對象在集合中只會存在一份

實現集合類

  • 在ES6中的Set類就是一個集合類,這裡我們重新封裝一個Set類,了解集合的底層實現。

  • JavaScript中的Object類中的key就是一個集合,可以使用它來封裝集合類Set。

集合常見的操作

  • add(value):向集合添加一個新的項;

  • remove(value):從集合中移除一個值;

  • has(value):如果值在集合中,返回true,否則返回false

  • clear():移除集合中的所有項;

  • size():返回集合所包含元素的數量,與數組的length屬性相似;

  • values():返回一個包含集合中所有值的數組;

還有其他的方法,用的不多這裡不做封裝;

1.2.代碼實現

    //封裝集合類      function Set() {        //屬性        this.items = {}          //方法        //一.has方法        Set.prototype.has = value => {          return this.items.hasOwnProperty(value)        }          //二.add方法        Set.prototype.add = value => {          //判斷集合中是否已經包含該元素          if (this.has(value)) {            return false          }          //將元素添加到集合中          this.items[value] = value//表示該屬性鍵和值都為value          return true//表示添加成功        }          //三.remove方法        Set.prototype.remove = (value) => {          //1.判斷集合中是否包含該元素          if (!this.has(value)) {            return false          }            //2.將元素從屬性中刪除          delete this.items[value]          return true        }          //四.clear方法        Set.prototype.clear = () => {          //原來的對象沒有引用指向,會被自動回收          this.items = {}        }          //五.size方法        Set.prototype.size = () => {          return Object.keys(this.items).length        }          //獲取集合中所有的值        //六.values方法        Set.prototype.values = function() {          return Object.keys(this.items)        }      }

測試代碼:

    //測試集合類      //1.創建Set類對象      let set = new Set()        //添加元素      //2.測試add方法      console.log(set.add('a'));                                      //67      console.log(set.add('a'));                                      //68      console.log(set.add('b'));                                      //69      console.log(set.add('c'));                                      //70      console.log(set.add('d'));                                      //71        //3.測試values方法      console.log(set.values());                                      //74        //刪除元素      //4.測試remove方法      console.log(set.remove('a'));                                   //78      console.log(set.remove('a'));                                   //79      console.log(set.values());                                      //80        //5.測試has方法      console.log(set.has('b'));                                      //83        //6.測試size方法和clear方法      console.log(set.size());                                        //86      set.clear()      // 由於clear方法的實現原理為指向另外一個空對象,所以不影響原來的對象      console.log(set.size());                                        //89      console.log(set.values());                                      //90

測試結果:

image-20200228183431635

1.3.集合間的操作

集合間操作:

  • 並集:對於給定的兩個集合,返回一個包含兩個集合中所有元素的新集合;
  • 交集:對於給定的兩個集合,返回一個包含兩個集合中共有元素的新集合;
  • 差集:對於給定的兩個集合,返回一個包含所有存在於第一個集合且不存在於第二個集合的元素的新集合;
  • 子集:驗證一個給定集合是否是另一個集合的子集;

image-20200228210239984

並集的實現:

實現思路:創建集合C代表集合A和集合B的並集,先將集合A中的所有元素添加到集合C中,再遍歷集合B,如果是集合C所沒有的元素就把它添加到集合C中。

 Set.prototype.union = otherSet => {        // this:集合對象A        // otherSet:集合對象B        //1.創建一個新的集合        let unionSet = new Set()          //2.將A集合中的所有元素添加到新集合中        let values = this.values()        // for(let i of values){        //   unionSet.add(i)        // }        for(let i = 0;i < values.length;i++){          unionSet.add(values[i])        }          //3.取出B集合中的元素,判斷是否需要加到新集合中        values = otherSet.values()        // for(let i of values){        //   //由於集合的add方法已經對重複的元素進行了判斷,所以這裡可以直接添加        //   unionSet.add(i)        // }        for(let i = 0;i < values.length;i++){          unionSet.add(values[i])        }        return unionSet      }

交集的實現:

實現思路:遍歷集合A,當取得的元素也存在於集合B時,就把該元素添加到另一個集合C中。

 Set.prototype.intersection = otherSet => {        // this:集合A        // otherSet:集合B        //1.創建新的集合        let intersectionSet = new Set()          //2.從A中取出一個元素,判斷是否同時存在於集合B中,是則放入新集合中        let values = this.values()        for(let i =0 ; i < values.length; i++){          let item = values[i]          if (otherSet.has(item)) {            intersectionSet.add(item)          }        }        return intersectionSet      }

差集的實現:

實現思路:遍歷集合A,當取得的元素不存在於集合B時,就把該元素添加到另一個集合C中。

Set.prototype.diffrence = otherSet => {          //this:集合A          //otherSet:集合B          //1.創建新的集合          var diffrenceSet = new Set()            //2.取出A集合中的每一個元素,判斷是否同時存在於B中,不存在則添加到新集合中          var values = this.values()          for(var i = 0;i < values.length; i++){            var item = values[i]            if (!otherSet.has(item)) {              diffrenceSet.add(item)            }          }          return diffrenceSet        }

子集的實現:

實現思路:遍歷集合A,當取得的元素中有一個不存在於集合B時,就說明集合A不是集合B的子集,返回false。

 Set.prototype.subset = otherSet => {          //this:集合A          //otherSet:集合B          //遍歷集合A中的所有元素,如果發現,集合A中的元素,在集合B中不存在,那麼放回false,如果遍歷完整個集合A沒有返回false,就返回true          let values = this.values()          for(let i = 0; i < values.length; i++){            let item = values[i]            if(!otherSet.has(item)){              return false            }          }          return true        }

二、字典結構

2.1.簡介

字典的特點

  • 字典存儲的是鍵值對,主要特點是一一對應;
  • 比如保存一個人的信息:數組形式:[19,『Tom』,1.65],可通過下標值取出信息;字典形式:{"age":19,"name":"Tom","height":165},可以通過key取出value。
  • 此外,在字典中key不能重複無序的,而Value可以重複

字典和映射的關係

  • 有些編程語言中稱這種映射關係字典,如Swift中的Dictonary,Python中的dict;
  • 有些編程語言中稱這種映射關係Map,比如Java中的HashMap&TreeMap等;

字典類常見的操作

  • set(key,value):向字典中添加新元素。
  • remove(key):通過使用鍵值來從字典中移除鍵值對應的數據值。
  • has(key):如果某個鍵值存在於這個字典中,則返回true,反之則返回false
  • get(key):通過鍵值查找特定的數值並返回。
  • clear():將這個字典中的所有元素全部刪除。
  • size():返回字典所包含元素的數量。與數組的length屬性類似。
  • keys():將字典所包含的所有鍵名以數組形式返回。
  • values():將字典所包含的所有數值以數組形式返回。

2.2.封裝字典

字典類可以基於JavaScript中的對象結構來實現,比較簡單,這裡直接實現字典類中的常用方法。

//封裝字典類  function Dictionary(){    //字典屬性    this.items = {}      //字典操作方法    //一.在字典中添加鍵值對    Dictionary.prototype.set = function(key, value){      this.items[key] = value    }      //二.判斷字典中是否有某個key    Dictionary.prototype.has = function(key){      return this.items.hasOwnProperty(key)    }      //三.從字典中移除元素    Dictionary.prototype.remove = function(key){      //1.判斷字典中是否有這個key      if(!this.has(key)) return false        //2.從字典中刪除key      delete this.items[key]      return true    }      //四.根據key獲取value    Dictionary.prototype.get = function(key){      return this.has(key) ? this.items[key] : undefined    }      //五.獲取所有keys    Dictionary.prototype.keys = function(){      return Object.keys(this.items)    }      //六.size方法    Dictionary.prototype.keys = function(){      return this.keys().length    }      //七.clear方法    Dictionary.prototype.clear = function(){      this.items = {}    }  }