ES6 中的 Set


收錄待用,修改轉載已取得騰訊雲授權


作者:kurtshen

ES6 新增了幾種集合類型,本文主要介紹Set以及其使用。

其基本描述為

Set對象是值的集合,你可以按照插入的順序迭代它的元素。 Set中的元素只會出現一次,即 Set 中的元素是唯一的。

它的聲明

new Set([iterable]);

其中iterable是一個可迭代對象,其中的所有元素都會被加入到 Set 中。null被視作 undefined。也可以不傳入[iterable],通過其add方法來添加元素。

對於ruby或者是python比較熟悉的同學可能會比較了解set這個東東。它是ES6 新增的有序列表集合,它不會包含重復項。

Set的屬性

  • Set.prototype.size:返回Set實例的成員數量。
  • Set.prototype.constructor:默認的構造Set函數。

Set方法

  • add(value):添加某個值,返回Set結構本身。
  • delete(value):刪除某個值,返回一個布爾值,表示刪除成功。
  • has(value):返回一個布爾值,表示參數是否為Set的成員。
  • clear():清除所有成員,沒有返回值。
  • keys() :返回一個鍵名的遍歷器
  • values() :返回一個值的遍歷器
  • entries() :返回一個鍵值對的遍歷器
  • forEach():使用回調函數遍歷每個成員

例子

先借用之前看過的一篇英文blog的例子。地址請戳Removing Elements from JavaScript Arrays

總所周知,數組是沒有remove這個方法的。當我們需要從一個數組里面移除一個特定的元素時,我們通常會怎么寫?

在es6之前,我們會這么寫

function remove(array, element) {
    const index = array.indexOf(element);
    array.splice(index, 1);
}

然后我們可以這么用

const arr = ["a", "e", "i", "o", "u", "x"];
arr; //["a", "e", "i", "o", "u", "x"]

// 移除其中的“x”
remove(arr, "x");
arr; // ["a", "e", "i", "o", "u"]

// 細心的同學會發現我們前面那么寫的問題,如果我們再次移除“x”的話,會發生移除最后一個元素
remove(arr, "x");
arr; // ["a", "e", "i", "o"]

當數組查找不到某元素時會返回-1,則數組的splice會從末尾往前,移除了最后一個元素,於是我們會這么寫

function remove(array, element) {
    const index = array.indexOf(element);

    if (index !== -1) {
        array.splice(index, 1);
    }
}

這樣的話我們就每次總是需要去檢測index的值。

我們還可以用filter來寫remove,這樣則返回一個新的數組

function remove(array, element) {
    return array.filter(e => e !== element);
}

那么有了Set我們能怎寫?其實也不需要寫,因為set其初始化可以接受一個數組,作為構造參數,另外自帶了一個delete的方法

const set = new Set(["a", "e", "i", "o", "u", "x"]);
set.delete("x"); // true
set; // Set {"a", "e", "i", "o", "u"}

set.delete("x"); // false
set; // Set {"a", "e", "i", "o", "u"}

好像蠻好的,但其實Set集合中的值是不能重復的,如果所需要的數據結構是要允許有重復項的,那么Set也沒有什么用。

Set中值的相等是這么說的

因為 Set 中的值總是唯一的,所以需要判斷兩個值是否相等。判斷相等的算法與嚴格相等(=操作符)不同。具體來說,對於 Set , +0 (+0 嚴格相等於-0)和-0是不同的值。盡管在最新的 ECMAScript 6規范中這點已被更改。從Gecko 29.0和 recent nightly Chrome開始,Set 視 +0 和 -0 為相同的值。另外,NaN和undefined都可以被存儲在Set 中, NaN之間被視為相同的值(盡管 NaN ! NaN)。

另一個例子

既然它的值是唯一的,那么我們是不是可以用它來實現數組去重?

原先我們去重可能會這么寫

let arr = [1,'1', 2, 3, 2, 4, 5, 4, 1];
let arr_unique = arr.filter(function(item, index, array) {
return array.indexOf(item, index + 1) === -1;
});
arr_unique;//["1", 3, 2, 5, 4, 1]

或者利用對象key的唯一性,這么寫

let arr = [1,'1', 2, 3, 2, 4, 5, 4, 1];
let tmpObj = {};
let arr_unique = [];
arr.forEach(function(a) {
  let key = (typeof a) + a;
  if (!tmpObj[key]) {
    tmpObj[key] = true;
    arr_unique.push(a);
  }
});
arr_unique;//[1, "1", 2, 3, 4, 5]

於是現在還能這么寫

let arr = [1,'1', 2, 3, 2, 4, 5, 4, 1];
let set = new Set(arr);
let arr_unique = Array.from(set);//Array新增了一個靜態方法Array.from,可以把類似數組的對象轉換為數組
arr_unique;//[1, "1", 2, 3, 4, 5]

除了Array.from,我們也可以這么轉化數組

let set = new Set(['a','b','c']);
let arr = [...set];
arr;//['a','b','c']

而利用Array與Set的相互轉化,還可以很容易地實現並集(Union)和交集(Intersect)

let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2]);
let union = new Set([...a, ...b]);
union;// [1, 2, 3, 4]
let intersect = new Set([...a].filter(x => b.has(x)));
intersect;// [2, 3]

總結

與Array相比:

  • Set中存儲的元素是唯一的,而Array中可以存儲重復的元素。
  • Set中遍歷元素的方式:Set通過for…of…,而Array通過for…in…。
  • Set是集合,不能像數組用下標取值。

原文鏈接:http://ivweb.io/topic/582925cd9554d860548c1fa3


原文鏈接:https://www.qcloud.com/community/article/592399001489391635


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM