數據結構 Set 與 Array
一、Set 與 Array 是什么
-
Set 是 ES6 提供的一種新的數據結構。Set 中的元素只會出現一次,即 Set 中的元素是唯一的。Set 是值的集合。
-
Array 中的元素可以是原始類型或對象類型。Array 是有序數據的集合。
二、Set 的用途
Set 類似於 Array,同 Array 方法中有相似之處。Set 的一個特性是,沒有相同的成員(完全相等的成員)。
-
所以在不需要有重復元素的情況下,可以用 Set 數據結構來替代 Array。
-
同時,因為這一特性,可以用 Set 數據結構來轉換沒有重復的數組。
三、生成 Set 和 Array 數據結構
- Set 數據結構使用構造函數 Set 來生成。
const s = new Set();
console.log(s) // Set []
- Array 數組也可以用 Array 構造函數來生成.
const arr = new Array();
console.log(arr) // Array[]
四、Set 與 Array 對比
屬性對比
- 獲取數據結構元素個數
- Set 數據結構通過 size 來獲取成員的數量。無法改變 size 的值。
const s = new Set();
s.add(1).add(2);
console.log(s.size); // 2
s.size = 3; // 3
console.log(s.size); // 2, size 值不可以改變
- Array 數組通過 length 來獲取成員的數量。length 的值可以改變。
const arr1 = new Array(2);
console.log(arr1.length) // 2(如果用 Array 構造函數創建的數組,其值只有一個,且該值為數字,則該值表示的是該數組的長度)
console.log(arr1) // [empty × 2]
const arr2 = new Array(1, 2, 3);
console.log(arr2.length) // 3
arr2.length = 2;
console.log(arr2.length); // 2,lenght 值可以改變
方法對比
- 添加元素
- Set 數據結構通過 add() 方法在末尾添加一個指定的值,返回對象本身。不能添加重復的值。
const s = new Set();
console.log(s) // Set []
s.add(1);
console.log(s) // Set [ 1 ]
s.add(2).add('hello'); // 可以鏈式調用
console.log(s) // Set(3) [ 1, 2, 'hello' ]
s.add(2); // 試圖添加一個重復的值 2
console.log(s) // Set(3) [ 1, 2, 'hello' ]
- Array 數組通過 push() 方法將一個或多個元素添加到數組的末尾,並返回該數組的新長度。
const animals = ['pigs', 'goats', 'sheep'];
const count = animals.push('cows');
console.log(count) // 4
console.log(animals) // Array ["pigs", "goats", "sheep", "cows"]
- Array 數組通過 unshift() 方法將一個或多個元素添加到數組的開頭,並返回該數組的新長度(該方法修改原有數組)。
const arr1 = [1, 2, 3];
console.log(arr1.unshift(4, 5)); // 5
console.log(arr1); // Array [4, 5, 1, 2, 3]
- Array 數組通過 splice() 方法通過刪除或替換現有元素或者原地添加新的元素來修改數組,並以數組形式返回被修改的內容(此方法會改變原數組)。
const months = ['Jan', 'March', 'April', 'June'];
months.splice(1, 0, 'Feb'); // 在索引為 1 的位置刪除 0 個元素,添加 'Feb' 元素
console.log(months); // Array ["Jan", "Feb", "March", "April", "June"]
- 刪除元素
- Set 數據結構通過 delete() 方法刪除指定的元素(成功刪除返回 true,否則返回 false)。
const s9 = new Set();
s9.add(1).add(2).add(3); // Set(3) [ 1, 2, 3 ]
s9.delete(4) // false
s9.delete(3) // true
- Array 數組通過 pop()方法從數組中刪除最后一個元素,並返回該元素的值(此方法更改數組的長度)。
const team = ["前端產品組", "前端產品組", "前端產品組", "軍工算法組"];
const popped = team.pop();
console.log(team) // ["前端產品組", "前端產品組", "前端產品組"]
console.log(popped) // "軍工算法組"
- Array 數組通過 shift() 方法從數組中刪除第一個元素,並返回該元素的值(此方法更改數組的長度)。
const fruits = ['banana', 'apple', 'orange'];
const shifted = fruits.shift();
console.log(shifted) // "banana"
console.log(fruits) // Array ["apple", "orange"]
- Array 數組通過 splice() 方法通過刪除或替換現有元素或者原地添加新的元素來修改數組,並以數組形式返回被修改的內容(此方法會改變原數組)。
const years = ['1919', '2008', '2018', '2020'];
const spliced = years.splice(1, 1); // 在索引為 1 的位置刪除 1 個元素
console.log(spliced); // "2008"
console.log(years); // Array ["1919", "2018", "2020"]
- 清空元素
- Set 數據結構通過 clear() 方法清空元素成員。返回值 undefined。
let s = new Set();
s.add(1);
s.add("foo");
s.size; // 2
s.has("foo"); // true
s.clear();
s.size; // 0
s.has("bar") // false
- Array 數組通過將 length 屬性設置為 0,來清空數組。
let arr = new Array(4, 5, 6);
arr.length = 0;
console.log(arr); // Array []
console.log(arr.length); // 0
- Array 數組通過將值設置為空數組,來清空數組。
let arr = new Array(4, 5, 6);
arr = [];
console.log(arr); // Array []
console.log(arr.length); // 0
- 判斷元素是否存在
- Set 數據結構通過 has() 來指示對應的值 value 是否存在 Set 對象中。如果指定的值 value 存在於 Set 對象當中,返回 true;否則返回 false。
const s = new Set();
s.add('foo');
console.log(s.has('foo')); // true
console.log(s.has('bar')); // false
- Array 數組通過 includes() 方法用來判斷一個數組是否包含一個指定的值,根據情況,如果包含則返回 true,否則返回 false。
const pets = ['cat', 'dog'];
console.log(pets.includes('cat')); // true
console.log(pets.includes('pig')); // false
- Array 數組通過 indexOf() 方法返回在數組中可以找到一個給定元素的第一個索引。如果不存在,則返回 -1,如果存在則返回索引。
const beasts = ['ant', 'camel', 'duck', 'ant'];
console.log(beasts.indexOf('ant')); // 0
console.log(beasts.indexOf('ant', 2)); // 3
console.log(beasts.indexOf('dog')); // -1
- 迭代元素
- Set 可以使用 forEach() 遍歷成員。
let s = new Set([1, 4, 9]);
s.forEach((value, key) => console.log(key + ' : ' + value))
// 1 : 1
// 4 : 4
// 9 : 9
第一個參數是處理函數,該函數的參數依次是 “健值,健名,集合本身”。Set 結構的健值就是健名,所以第一個參數和第二個參數永遠相同。
- Array 也可以使用 forEach() 遍歷成員。
let arr = new Array(1, 4, 9);
arr.forEach((value, index) => console.log(index + ' : ' + value));
// 0 : 1
// 1 : 4
// 2 : 9
與 Set 數據結構不同的是,Array 數組的健名是從 0 開始的有序整數。也稱為索引。
- Set 數據結構還包含 keys(), values(), entries() 方法來遍歷健名、健值、健值對。返回對應的遍歷器。通過 for of 來遍歷遍歷器。
let set = new Set(['red', 'green', 'blue']);
for (let item of set.keys()) {
console.log(item);
}
// red
// green
// blue
let set = new Set(['red', 'green', 'blue']);
for (let item of set.values()) {
console.log(item);
}
// red
// green
// blue
let set = new Set(['red', 'green', 'blue']);
for (let item of set.entries()) {
console.log(item);
}
// Array [ "red", "red" ]
// Array [ "green", "green" ]
// Array [ "blue", "blue" ]
五、Set 與 Array 轉換
- Set 轉 Array
Array.from() 方法可以將 Set 數據結轉為數組。
const setItems = new Set([1, 2, 3, 4, 5]);
const arrayItems = Array.from(setItems);
console.log(setItems); // Set(5) [ 1, 2, 3, 4, 5 ]
console.log(arrayItems); // Array(5) [ 1, 2, 3, 4, 5 ]
因為 Set 可迭代,也即 Set 具有 Iterator 接口。所以使用擴展運算符 ... 也可以將 Set 數據結構轉換成 Array。
const setItems = new Set([1, 2, 3, 4, 5]);
const arrayItems = [...setItems];
console.log(setItems); // Set(5) [ 1, 2, 3, 4, 5 ]
console.log(arrayItems); // Array(5) [ 1, 2, 3, 4, 5 ]
- Array 轉 Set
Set 構造函數可以接受一個數組作為參數,用來初始化。實現 Array 轉 Set。
const srrayItems = ['hello', 'world'];
const setItems = new Set(srrayItems);
console.log(srrayItems); // Array [ "hello", "world" ]
console.log(setItems); // Set [ "hello", "world" ]
六、數組去重
因為 Set 數據結構無法添加重復的元素,所以 Set 構造函數很適合用來去除數組中重復的的元素。
- 先使用 Set 構造函數,去除數組中重復的元素;再使用擴展運算符 ... 轉換為數組。
[...new Set([1, 2, 3, 3, 2])]; // Array [ 1, 2, 3 ]
同理,字符串可以用類似的方法去重。
[...new Set('ababbc')].join(''); // "abc"
- 另一種去重方法是先使用 Set 構造函數,去除數組中重復的元素;再使用擴展運算符 Array.from() 方法轉換為數組。
Array.from(new Set([1, 2, 3, 3, 2])); // Array [ 1, 2, 3 ]
