ES6 - 數據結構 Set() 與 Map()
Set() 與 Map() 產生出來的數據結構看起來像 Array 但卻是不同的資料類型,它們都有 Symbol.iterator
這個原型方法,具有可迭代的特性。
Set()
Set 最大的特點就是 "產生一組不重複值的資料",只要資料型態本身具有 iterator 的特性 Set 就能接收並轉成過濾後的資料。 不過 Set 產生的資料無法個別訪問也不具有 index,比較像是單純的一組值,靠新增刪除等方式直接對值做處理。如果要取用這些值,就需要轉換成 array 的型態,或是使用 for...of、forEach 等迭代方法將值挖出來。
new Set()
建立 Set.add(val)
新增值.delete(val)
刪除值.clear()
清除整組 Set.size
取得 Set 值的總數.has(val)
檢查是否已經有值,回傳布林值.values()
取得 Set 的 values iterator.keys()
取得 Set 的 keys iterator,但 key 與值其實相同.entries()
同時取得 Set 的 key 跟 value,格式看起來會是 [key, value] 的 iterator.forEach()
遍歷 Set 每筆資料
js
const people = new Set(); // 建立空的 Set
people.add('Mary'); // 新增 Mary
people.add('Ben'); // 新增 Ben
console.log(people.size); // 2,裡面有2筆資料
people.delete('Ben'); // 刪除 Ben,直接帶值進去
console.log(people.size); // 1,裡面有1筆資料
console.log(people.has('Ben')); // false
people.clear(); // 清空 Set
console.log(people.size); // 0,裡面沒資料
// 使用 values()、keys()、entries() 雖然可以取得資料,
// 但無法直接取用,要真正把值抓出來需要使用迭代方法將他們遍歷出來
people.add('Mary'); // 新增 Mary
people.add('Ben'); // 新增 Ben
console.log(people.values()); // 只會顯示是個 Set iterator 物件
people.forEach((val, key)=>{
console.log(`${key}:${val}`);
}); // "Mary:Mary", "Ben:Ben"
這樣寫下來好像比用 Array 更麻煩,但如果把 Set 與 Array 結合的話就會方便很多!
js
// 直接在 new Set() 的同時帶入一筆 array 資料
const num = new Set([1,2,3,4,5,4,3,6,7]);
console.log(num.size); // 結果是 7,已刪除重複的數字
const numArray = Array.from(num); // 使用 Array.from() 來轉成 Array 型態
console.log(numArray); // [1, 2, 3, 4, 5, 6, 7] 變回乾淨的 Array 啦!
// 上例也可以簡化成一行搞定
const numFilter = Array.from(new Set([1,2,3,4,5,4,3,6,7]));
// 也可以使用 ES6 的展開語法
const numFilter = [...new Set([1,2,3,4,5,4,3,6,7])];
Map()
Map 提供了一種類似 "Object" 具有 key 與 value 的資料型態,但存放方式又像 "Array",一筆資料本身會有兩個值,第一個值是 key,第二個值是 value,因此一組 Map 會是二維陣列的形式呈現。而新增刪除 Map 資料時會是以 key 作為辨識。Map 資料在遍歷時,順序是跟最初設定值的順序一樣。
new Map()
建立 Map.set(key, val)
設定屬性跟值.get(key)
取得 key 的值.delete(key)
刪除這組 key 值.clear()
清除 Map.size
取得 Map 的總數.has(key)
檢查是否已經有 key,回傳布林值.keys()
取得 Map 的 keys iterator.values()
取得 Map 的 values iterator.entries()
同時取得 Map 的 key 跟 value,格式看起來會是 [key, value] 的 iterator.forEach()
遍歷 Map 每筆資料
js
const family = new Map(); // 建立空 Map
family.set('Mom', 70); // set 來設定 key 跟 value
family.set('Dad', 70);
console.log(family.get('Mom')); // 70, get 使用 key 來取得 value
// 一樣可以使用 forEach 遍歷
family.forEach((value, key)=>{console.log(value, key)});
// 使用 for of 的話則是抓出 [key, value] 的陣列
for (const person of family){
console.log(person); //['Mom', 70],['Dad', 70]
}
// Map 一樣可轉為一般陣列
console.log([...family.keys()]); // ["Mom", "Dad"]
console.log([...family.values()]); // [70, 70]
console.log([...family.entries()]); // [["Mom", 70], ["Dad", 70]]
// 當然轉成 Object 也沒問題
const familyObj = {};
for (let [key, val] of family) {
familyObj[key] = val;
}
console.log(familyObj); // { Dad: 70, Mom: 70 }