Set 數(shù)據(jù)結(jié)構(gòu)
一、基本用法
1、數(shù)據(jù)結(jié)構(gòu)Set,類(lèi)似于數(shù)組,成員的值都是唯一的,沒(méi)有重復(fù)的值。
2、Set本身是一個(gè)構(gòu)造函數(shù),用來(lái)生成Set數(shù)據(jù)結(jié)構(gòu)。
const s = new Set();
[2, 3, 5, 4, 5, 2, 2].forEach(x => s.add(x));
for (let i of s) {
console.log(i);
}
// 2 3 5 4
3、Set函數(shù)去除數(shù)組重復(fù)成員的方法。
(1)去除數(shù)組的重復(fù)成員
let arr = [3, 5, 2, 2, 5, 5];
[...new Set(arr)]
(2)去除數(shù)組重復(fù)成員的另一種方:
function dedupe(array) {
return Array.from(new Set(array));
}
dedupe([1, 1, 2, 3]) // [1, 2, 3]
4、向Set加入值的時(shí)候,不會(huì)發(fā)生類(lèi)型轉(zhuǎn)換,所以5和"5"是兩個(gè)不同的值。Set內(nèi)部判斷兩個(gè)值是否相等。使用的算法叫做"Same-value-zero equality",它類(lèi)似于精確運(yùn)算符(===),主要區(qū)別是NaN等于自身,而精確相等運(yùn)算符認(rèn)為NaN不等于自身。
let set = new Set();
let a = NaN;
let b = NaN;
set.add(a);
set.add(b);
set // Set {NaN}
注:只能向Set實(shí)例中加入一個(gè)NaN,這表明,在Set內(nèi)部,兩個(gè)NaN是相等。(對(duì)象總是不相等的)
二、Set實(shí)例的屬性和方法
1、Set結(jié)構(gòu)的實(shí)例屬性:
????????- Set.prototype.constructr:構(gòu)造函數(shù),默認(rèn)就是Set函數(shù)。
????????- Set.prototype.size:返回Set實(shí)例的成員總數(shù)。
2.Set實(shí)例的方法分為兩大類(lèi):操作方法(用于操作數(shù)據(jù))和遍歷方法(用于遍歷成員)。
????????- add(value):添加某個(gè)值,返回Set結(jié)構(gòu)本身。
????????- delete(value):刪除某個(gè)值,返回一個(gè)布爾值,表示刪除是否成功。
????????- has(value):返回一個(gè)布爾值,表示該值是否為Set成員。
????????- clear():清除所有成員,沒(méi)有返回值。
屬性和方法的實(shí)例:
s.add(1).add(2).add(2);
// 注意2被加入了兩次
s.size // 2
s.has(1) // true
s.has(2) // true
s.has(3) // false
s.delete(2);
s.has(2) // false
3、Array.from方法可以將Set結(jié)構(gòu)轉(zhuǎn)為數(shù)組。
const items = new Set([1, 2, 3, 4, 5]);
const array = Array.from(items);
三、遍歷操作
1、Set的結(jié)構(gòu)實(shí)例的遍歷方法
????????- keys():返回鍵名的遍歷器
????????- values():返回鍵值的遍歷器
????????- entries():返回鍵值對(duì)的遍歷器
????????- forEach():使用回調(diào)函數(shù)遍歷每個(gè)成員
注:Set結(jié)構(gòu)的鍵名和鍵值,兩者是同一個(gè)值。
2、使用Set可以很容易地實(shí)現(xiàn)并集(Union)、交集(Intersect)和差集(Difference)。
let a = new Set([1, 2, 3]);let b = new Set([4, 3, 2]);
// 并集
let union = new Set([...a, ...b]);
// Set {1, 2, 3, 4}
// 交集
let intersect = new Set([...a].filter(x => b.has(x)));
// set {2, 3}
// 差集
let difference = new Set([...a].filter(x => !b.has(x)));
// Set {1}
Map 數(shù)據(jù)結(jié)構(gòu)
一、含義和基本用法
1、Map 數(shù)據(jù)結(jié)構(gòu)。它類(lèi)似于對(duì)象,也是鍵值對(duì)的集合,但是“鍵”的范圍不限于字符串,各種類(lèi)型的值(包括對(duì)象)都可以當(dāng)作鍵。
二、實(shí)例的屬性和操作方法
1、size屬性
size屬性返回Map結(jié)構(gòu)的成員總數(shù)。
例:
const map = new Map();
map.set('foo', true);
map.set('bar', false);
map.size // 2
2、set(key,value)
set方法設(shè)置鍵名key對(duì)應(yīng)的鍵名為value,然后返回整個(gè)Map結(jié)構(gòu)。如果key已經(jīng)有值,則鍵值會(huì)被更新,否則就新成該鍵。
例:
const m = new Map();
m.set('edition', 6) // 鍵是字符串
m.set(262, 'standard') // 鍵是數(shù)值
m.set(undefined, 'nah') // 鍵是 undefined
3、get(key)
get方法讀取key對(duì)應(yīng)的鍵值,如果找不到key,返回undefined。
例:
const m = new Map();
const hello = function() {console.log('hello');};
m.set(hello, 'Hello ES6!') // 鍵是函數(shù)
m.get(hello) // Hello ES6!
4、has(key)
has方法返回一個(gè)布爾值,表示某個(gè)鍵是否在當(dāng)前Map對(duì)象之中。
例:
const m = new Map();
m.set('edition', 6);
m.set(262, 'standard');
m.set(undefined, 'nah');
m.has('edition') // true
m.has('years') // false
m.has(262) // true
m.has(undefined) // true
5、delete(key)
delete方法刪除某個(gè)鍵,返回true。如果刪除失敗,返回false。
例:
const m = new Map();
m.set(undefined, 'nah');
m.has(undefined) // true
m.delete(undefined)
m.has(undefined) // false
6、clear()
clear方法清除所有成員,沒(méi)有返回值。
例:
let map = new Map();
map.set('foo', true);
map.set('bar', false);
map.size // 2
map.clear()
map.size // 0
三、遍歷方法
1、Map結(jié)構(gòu)提供了三個(gè)遍歷器生成函數(shù)和一個(gè)遍歷方法。
????????- keys():返回鍵名的遍歷器。
????????- values():返回鍵值的遍歷器。
????????- entries():返回所有成員的遍歷器。
????????- forEach():遍歷 Map 的所有成員。
四、與其他數(shù)據(jù)結(jié)構(gòu)的互相轉(zhuǎn)換
1、Map轉(zhuǎn)位數(shù)組
使用擴(kuò)展運(yùn)算符,是最為方便的方法。
例:
const myMap = new Map()
.set(true, 7)
.set({foo: 3}, ['abc']);[...myMap]
// [ [ true, 7 ], [ { foo: 3 }, [ 'abc' ] ] ]
2、數(shù)組轉(zhuǎn)為Map
將數(shù)組傳入Map構(gòu)造函數(shù),就可以轉(zhuǎn)為Map。
例:
new Map([
[true, 7],
[{foo: 3}, ['abc']]])
// Map {
// true => 7,
// Object {foo: 3} => ['abc']
// }
3、Map轉(zhuǎn)為對(duì)象
如果所有Map的鍵都是字符串,就可以無(wú)損的轉(zhuǎn)為對(duì)象;如果有非字符串的鍵名,鍵名也會(huì)被轉(zhuǎn)為字符串,在作為對(duì)象的鍵名。
例:
function strMapToObj(strMap) {
let obj = Object.create(null);
for (let [k,v] of strMap) {
obj[k] = v;
}
return obj;
}
const myMap = new Map()
.set('yes', true)
.set('no', false);strMapToObj(myMap)
// { yes: true, no: false }
4、對(duì)象轉(zhuǎn)為Map
例:
function objToStrMap(obj) {
let strMap = new Map();
for (let k of Object.keys(obj)) {
strMap.set(k, obj[k]);
}
return strMap;
}
objToStrMap({yes: true, no: false})
// Map {"yes" => true, "no" => false}
5、Map轉(zhuǎn)為JSON
(1)Map鍵名都是字符串,這時(shí)可以選擇轉(zhuǎn)為對(duì)象JSON。
例:
function strMapToJson(strMap) {
return JSON.stringify(strMapToObj(strMap));
}
let myMap = new Map().set('yes', true).set('no', false);strMapToJson(myMap)
// '{"yes":true,"no":false}'
(2)Map的鍵名有非字符串,這時(shí)可以選擇轉(zhuǎn)為數(shù)組JSON。
例:
function mapToArrayJson(map) {
return JSON.stringify([...map]);
}
let myMap = new Map().set(true, 7).set({foo: 3}, ['abc']);mapToArrayJson(myMap)
// '[[true,7],[{"foo":3},["abc"]]]'
6、JSON轉(zhuǎn)為Map
JSOP轉(zhuǎn)為Map,正常情況下,所有鍵名都是字符串。
例:
function jsonToStrMap(jsonStr) {
return objToStrMap(JSON.parse(jsonStr));
}
jsonToStrMap('{"yes": true, "no": false}')
// Map {'yes' => true, 'no' => false}