ES6 中的 Set

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


做者:kurtshenjava

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

其基本描述爲es6

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

它的聲明算法

new Set([iterable]);數組

其中iterable是一個可迭代對象,其中的全部元素都會被加入到 Set 中。null被視做 undefined。也能夠不傳入[iterable],經過其add方法來添加元素。ruby

對於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

相關文章
相關標籤/搜索