第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

全部開發(fā)者教程

ES6-10 入門教程

ES6+ Set

1. 前言

上一節(jié),我們對 ES6 新的數(shù)據(jù)結(jié)構(gòu)做了簡要的介紹,并沒有深入的學(xué)習(xí)。這節(jié)我們將深入地學(xué)習(xí) Set 數(shù)據(jù)結(jié)構(gòu),了解 Set 的存儲方式,可以讓我們更深入地理解 Set 數(shù)據(jù)結(jié)構(gòu)。

2. 基本用法

Set 提供了用于操作數(shù)據(jù)的幾種方法,使用這些方法可以對 Set 上的數(shù)據(jù)進(jìn)行增、刪、查等操作,具體有以下 5 種方法:

方法名 描述
add 向 Set 實例中添加值
delete 刪除 Set 實例中的指定值
clear 清空 Set 實例
has 查找指定的值是否在 Set 實例中
size 返回集合存儲數(shù)據(jù)的長度

Set 不像數(shù)組可以用索引去查找存儲的數(shù)據(jù),所以 Set 沒有修改操作。Set 存儲的數(shù)據(jù)都是唯一的,而且可以是任意類型的數(shù)據(jù)。

在實例化一個 Set 數(shù)據(jù)結(jié)構(gòu)時,可以接受一個可遍歷的對象(一般為數(shù)組),作為默認(rèn)值,返回一個 Set 實例:

var set = new Set([1, 2, 3])
console.log(set) // Set(3) {1, 2, 3}

也可以使用 add 方法去添加元素,并且 add 方法支持鏈?zhǔn)秸{(diào)用:

// 創(chuàng)建一個空的 Set 實例
var set = new Set()        // Set(0) {}
// 添加數(shù)據(jù)
set.add('es6')             // Set(1) {"es6"}
// 還可以鏈?zhǔn)教砑訑?shù)據(jù)
set.add('imooc').add({age: '7'}) 
cosnole.log(set)	// 如下圖

圖片描述

上面的例子中,對 Set 實例添加元素,可以添加引用類型數(shù)據(jù)。Set 的存儲方式是以對象的形式存放的,所以 Set 的本質(zhì)也就是一個對象,它繼承 Object,我們可以通過原型鏈( __proto__ )找到最上層是 Object。

Set 還提供了一些方法用于刪除、查找和清空操作:

// 創(chuàng)建一個帶默認(rèn)值的 Set 實例
var set = new Set([1, 2, 3]);
// delete 刪除數(shù)據(jù): 刪除指定的數(shù)據(jù),或者清空數(shù)據(jù)
console.log(set.delete(3));
// set.size 可以統(tǒng)計多少條數(shù)據(jù),類似數(shù)組中的length屬性
console.log(set.size);        // 2
// clear 會清空Set實例
console.log(set.clear());    // Set(0) {}
// has 方法可以查看某個元素是否包含在 Set 實例中
console.log(set.has('a'));    // false
console.log(set.has(1));    // true

2. 案例:數(shù)組去重

Set 一個最常見的操作就是對數(shù)組進(jìn)行去重操作,這也是它誕生的一個主要功能之一。

在 ES5 中數(shù)組去重的方法很多,一種是使用 for 循環(huán)來對數(shù)組中的項進(jìn)行一一驗證,另一種是比較高效的方法就是借助對象的鍵是唯一的特性進(jìn)行去重操作。下面我們來實現(xiàn)這兩種方法,并對比 Set 方式去重。

2.1 使用 for 循環(huán)去重

使用 for 循環(huán)去重比較簡單,建立一個空數(shù)組,然后循環(huán)目標(biāo)數(shù)組,如果當(dāng)前循環(huán)的元素不在這個新建的數(shù)組中,就 push 到這個數(shù)組中。下面給出具體的代碼:

function unique(arr) {
    const newArr = []
    for (let i = 0; i < arr.length; i++) {
        if (newArr.indexOf(arr[i]) === -1) {
            newArr.push(arr[i])
        }
    }
    return newArr
}

這種方法比較簡單也是最常見的方法,雖然這里只有一次循環(huán),但是 indexOf 的查詢也是有時間復(fù)雜度的,所以不能單純地認(rèn)為這里的時間復(fù)雜度是 n。另外,由于 indexOf 存在一些缺陷這里也可以使用 includes() 進(jìn)行替換。

2.2 使用 hash 方法去重

使用 hash 方法去重是利用對象的鍵是唯一的,維護一個以數(shù)組中元素為 hash 表的鍵,由于鍵是唯一的,所以數(shù)組中相同的元素在 hash 表中只會有一個鍵。

  function unique(arr){
    const newArr = [];
    const hash = {};
    for(var i=0; i<arr.length; i++){
      if(!hash[arr[i]]){
        hash[arr[i]] = true;
        newArr.push(arr[i]);
      }
    }
    return newArr;
  }

上面的代碼時間復(fù)雜度是 n,只需要對數(shù)組進(jìn)行一次循環(huán)即可。把循環(huán)的元素存放在 hash 表中來記錄不重復(fù)的元素。如果 hash 表中找不到對應(yīng)的值則在 hash 表中添加一個記錄,并把該元素 push 到數(shù)組中。這樣的方式時間復(fù)雜度為 n,但是維持一個 hash 表需要更多的空間。

2.3 使用 Set 方法去重

我們知道 Set 是一個集合,其中的元素不能重復(fù),所以可以利用 Set 數(shù)據(jù)結(jié)構(gòu)的特點進(jìn)行去重操作。下面給出具體代碼:

function unique(arr) {
    return [...new Set(arr)]
}

上面的代碼可以看出,上節(jié)我們學(xué)習(xí)了 Set 和數(shù)組直接的轉(zhuǎn)換,可以使用 ... 語法展開 Set 實例就可以得到數(shù)組。當(dāng)然還可以使用 Array.from() 方法把 Set 數(shù)據(jù)結(jié)構(gòu)轉(zhuǎn)化為數(shù)組。這種方式在低版本瀏覽器是不能運行的。

其實上面三種方式都有一定的缺點:

  • 第一種方式,時間復(fù)雜度高;
  • 第二種方式,空間復(fù)雜度高;還有一個致命的缺點是,如果數(shù)組中的元素是對象形式,那么就不能使用此方法。因為對象的 key 只能是字符串,其解決方式可以使用 Map 數(shù)據(jù)結(jié)構(gòu)代替 hash 的存儲;
  • 第三種方式,需要更高級的瀏覽器。

3. Set 的擴展方法

Set 實例上的數(shù)據(jù)可以使用 forEach 進(jìn)行遍歷:

var set = new Set(['a', 'b', 'c'])

set.forEach((item) => {
    console.log(item)
})
// a
// b
// c

雖然在 Set 數(shù)據(jù)結(jié)構(gòu)中沒有索引的概念,但是 Set 提供了三個方法用于我們?nèi)ケ闅v Set 數(shù)據(jù)結(jié)構(gòu)。

方法名 描述
values 得到 Set 實例中的值作為一個可以遍歷的對象
keys 得到 Set 實例中的鍵作為一個可以遍歷的對象,鍵和值相等
entries 得到 Set 實例中的鍵值作為一個可以遍歷的對象

通過這三種方法得到的是一個可迭代對象(后面的迭代器小節(jié)會具體介紹),看如下實例:

var set = new Set(['a', 'b', 'c'])

set.keys();    // SetIterator {"a", "b", "c"}
set.values();  // SetIterator {"a", "b", "c"}
set.entries(); // SetIterator {"a" => "a", "b" => "b", "c" => "c"}

for(var [key, value] of set.entries()) {
    console.log(key, value)
}
// a, a
// b, b
// c, c

從上面的代碼中,使用這三個方法得到的數(shù)據(jù)可以被 for...of 進(jìn)行遍歷。而且這三個方法得到的數(shù)據(jù)是一個可以迭代的對象,對象上的鍵和值是相等的,這也是為什么 Set 中的數(shù)據(jù)是唯一的原因。

4. 小結(jié)

本節(jié)我們深入地學(xué)習(xí)了 Set 數(shù)據(jù)結(jié)構(gòu)的基本用法和它提供的三個擴展方法。另外,通過案例數(shù)組去重,深入了解了 Set 數(shù)據(jù)結(jié)構(gòu)的用途。 Set 數(shù)據(jù)結(jié)構(gòu)的本質(zhì)還是一個鍵值對的對象,只不過鍵和值是相等的,這也是 Set 集合中元素不能重復(fù)的原因之一。并且 Set 是一個構(gòu)造函數(shù),需要實例化一個 Set 數(shù)據(jù)結(jié)構(gòu)才能使用。