收錄待用,修改轉載已取得 "騰訊雲" 授權 作者:kurtshen ES6 新增了幾種集合類型,本文主要介紹Set以及其使用。 其基本描述為 Set對象是值的集合,你可以按照插入的順序迭代它的元素。 Set中的元素只會出現一次,即 Set 中的元素是唯一的。 它的聲明 new Set([iterab ...
收錄待用,修改轉載已取得騰訊雲授權
作者: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是集合,不能像數組用下標取值。
原文鏈接:https://www.qcloud.com/community/article/592399001489391635