【JS】10--Map和Set對象

Map和Set對象

前置知識
Map和Set對象是在ES6中被引入的适室,作為一種由key值標記的數(shù)據(jù)容器嫡意。
Map和Set對象承載的數(shù)據(jù)元素可以按照插入時的順序,被迭代遍歷捣辆。

1.Set對象

介紹:
Set數(shù)據(jù)結(jié)構(gòu)類似數(shù)組蔬螟,但所有成員的值唯一
Set本身為一個構(gòu)造函數(shù)罪帖,用來生成Set數(shù)據(jù)結(jié)構(gòu)促煮,使用add方法來添加新成員邮屁。

let a = new Set();
[1,2,2,1,3,4,5,4,5].forEach(x=>a.add(x));
for(let k of a){
    console.log(k)
};
// 1 2 3 4 5

基礎(chǔ)使用

let a = new Set([1,2,3,3,4]);
[...a]; // [1,2,3,4]
a.size; // 4
// 數(shù)組去重
[...new Set([1,2,3,4,4,4])];// [1,2,3,4]

注意

  • Set中添加值的時候,不會類型轉(zhuǎn)換菠齿,即5'5'是不同的佑吝。
[...new Set([5,'5'])]; // [5, "5"]

屬性和方法

  • 屬性:

    • Set.prototype.constructor:構(gòu)造函數(shù),默認就是Set函數(shù)绳匀。
    • Set.prototype.size:返回Set實例的成員總數(shù)芋忿。
  • 操作方法:

    • add(value):添加某個值,返回 Set 結(jié)構(gòu)本身疾棵。
    • delete(value):刪除某個值戈钢,返回一個布爾值,表示刪除是否成功是尔。
    • has(value):返回一個布爾值殉了,表示該值是否為Set的成員。
    • clear():清除所有成員拟枚,沒有返回值薪铜。
let a = new Set();
a.add(1).add(2); // a => Set(2) {1, 2}
a.has(2);        // true
a.has(3);        // false
a.delete(2);     // true  a => Set(1) {1}
a.clear();       // a => Set(0) {}

數(shù)組去重

let a = new Set([1,2,3,3,3,3]);

2.Set的應(yīng)用

數(shù)組去重

// 方法1
[...new Set([1,2,3,4,4,4])]; // [1,2,3,4]
// 方法2
Array.from(new Set([1,2,3,4,4,4]));    // [1,2,3,4]

遍歷和過濾

let a = new Set([1,2,3,4]);
// map 遍歷操作
let b = new Set([...a].map(x =>x*2));// b => Set(4) {2,4,6,8}
// filter 過濾操作
let c = new Set([...a].filter(x =>(x%2) == 0)); // b => Set(2) {2,4}

獲取并集恩溅、交集和差集

let a = new Set([1,2,3]);
let b = new Set([4,3,2]);
// 并集
let c1 = new Set([...a, ...b]);  // Set {1,2,3,4}
// 交集
let c2 = new Set([...a].filter(x => b.has(x))); // set {2,3}
// 差集
let c3 = new Set([...a].filter(x => !b.has(x))); // set {1}
  • 遍歷方法:
    • keys():返回鍵名的遍歷器隔箍。
    • values():返回鍵值的遍歷器。
    • entries():返回鍵值對的遍歷器脚乡。
    • forEach():使用回調(diào)函數(shù)遍歷每個成員蜒滩。

Set遍歷順序是插入順序,當保存多個回調(diào)函數(shù)奶稠,只需按照順序調(diào)用俯艰。但由于Set結(jié)構(gòu)沒有鍵名只有鍵值,所以keys()values()是返回結(jié)果相同窒典。

let a = new Set(['a','b','c']);
for(let i of a.keys()){console.log(i)};   // 'a' 'b' 'c'
for(let i of a.values()){console.log(i)}; // 'a' 'b' 'c'
for(let i of a.entries()){console.log(i)}; 
// ['a','a'] ['b','b'] ['c','c']

并且 還可以使用for...of直接遍歷Set蟆炊。

let a = new Set(['a','b','c']);
for(let k of a){console.log(k)};   // 'a' 'b' 'c'

forEach與數(shù)組相同,對每個成員執(zhí)行操作瀑志,且無返回值涩搓。

let a = new Set(['a','b','c']);
a.forEach((v,k) => console.log(k + ' : ' + v));

3. Map對象

由于傳統(tǒng)的JavaScript對象只能用字符串當做鍵,給開發(fā)帶來很大限制劈猪,ES6增加Map數(shù)據(jù)結(jié)構(gòu)昧甘,使得各種類型的值(包括對象)都可以作為鍵。
Map結(jié)構(gòu)提供了“值—值”的對應(yīng)战得,是一種更完善的 Hash 結(jié)構(gòu)實現(xiàn)充边。 基礎(chǔ)使用

let a = new Map();
let b = {name: 'leo' };
a.set(b,'my name'); // 添加值
a.get(b);           // 獲取值
a.size;      // 獲取總數(shù)
a.has(b);    // 查詢是否存在
a.delete(b); // 刪除一個值
a.clear();   // 清空所有成員 無返回

注意

  • 傳入數(shù)組作為參數(shù),指定鍵值對的數(shù)組
let a = new Map([
    ['name','leo'],
    ['age',18]
])

  • 如果對同一個鍵多次賦值浇冰,后面的值將覆蓋前面的值贬媒。
let a = new Map();
a.set(1,'aaa').set(1,'bbb');
a.get(1); // 'bbb'

  • 如果讀取一個未知的鍵,則返回undefined肘习。
new Map().get('abcdef'); // undefined

  • 同樣的值的兩個實例际乘,在 Map 結(jié)構(gòu)中被視為兩個鍵。
let a = new Map();
let a1 = ['aaa'];
let a2 = ['aaa'];
a.set(a1,111).set(a2,222);
a.get(a1); // 111
a.get(a2); // 222

遍歷方法: Map 的遍歷順序就是插入順序漂佩。

  • keys():返回鍵名的遍歷器脖含。
  • values():返回鍵值的遍歷器。
  • entries():返回所有成員的遍歷器投蝉。
  • forEach():遍歷 Map 的所有成員养葵。
let a = new Map([
    ['name','leo'],
    ['age',18]
])

for (let i of a.keys()){...};
for (let i of a.values()){...};
for (let i of a.entries()){...};
a.forEach((v,k,m)=>{
    console.log(`key:${k},value:${v},map:${m}`)
})

將Map結(jié)構(gòu)轉(zhuǎn)成數(shù)組結(jié)構(gòu)

let a = new Map([
    ['name','leo'],
    ['age',18]
])

let a1 = [...a.keys()];   // a1 => ["name", "age"]
let a2 = [...a.values()]; // a2 =>  ["leo", 18]
let a3 = [...a.entries()];// a3 => [['name','leo'], ['age',18]]

4. Map與其他數(shù)據(jù)結(jié)構(gòu)互相轉(zhuǎn)換

  • Map 轉(zhuǎn) 數(shù)組
let a = new Map().set(true,1).set({f:2},['abc']);
[...a]; // [[true:1], [ {f:2},['abc'] ]]

  • 數(shù)組 轉(zhuǎn) Map
let a = [ ['name','leo'], [1, 'hi' ]]
let b = new Map(a);

  • Map 轉(zhuǎn) 對象 如果所有 Map 的鍵都是字符串,它可以無損地轉(zhuǎn)為對象瘩缆。
    如果有非字符串的鍵名关拒,那么這個鍵名會被轉(zhuǎn)成字符串,再作為對象的鍵名咳榜。
function fun(s) {
  let obj = Object.create(null);
  for (let [k,v] of s) {
    obj[k] = v;
  }
  return obj;
}

const a = new Map().set('yes', true).set('no', false);
fun(a)
// { yes: true, no: false }

  • 對象 轉(zhuǎn) Map
function fun(obj) {
  let a = new Map();
  for (let k of Object.keys(obj)) {
    a.set(k, obj[k]);
  }
  return a;
}

fun({yes: true, no: false})
// Map {"yes" => true, "no" => false}
  • Map 轉(zhuǎn) JSON
    (1)Map鍵名都是字符串夏醉,轉(zhuǎn)為對象JSON:
function fun (s) {
    let obj = Object.create(null);
    for (let [k,v] of s) {
        obj[k] = v;
    }
    return JSON.stringify(obj)
}
let a = new Map().set('yes', true).set('no', false);
fun(a);
// '{"yes":true,"no":false}'

(2)Map鍵名有非字符串爽锥,轉(zhuǎn)為數(shù)組JSON:

function fun (map) {
  return JSON.stringify([...map]);
}

let a = new Map().set(true, 7).set({foo: 3}, ['abc']);
fun(a)
// '[[true,7],[{"foo":3},["abc"]]]'

  • JSON 轉(zhuǎn) Map
    (1)所有鍵名都是字符串:
function fun (s) {
  let strMap = new Map();
  for (let k of Object.keys(s)) {
    strMap.set(k, s[k]);
  }
  return strMap;
  return JSON.parse(strMap);
}
fun('{"yes": true, "no": false}')
// Map {'yes' => true, 'no' => false}

(2)整個 JSON 就是一個數(shù)組涌韩,且每個數(shù)組成員本身,又是一個有兩個成員的數(shù)組:

function fun2(s) {
  return new Map(JSON.parse(s));
}
fun2('[[true,7],[{"foo":3},["abc"]]]')
// Map {true => 7, Object {foo: 3} => ['abc']}

參考資料

1.阮一峰ES6入門

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末氯夷,一起剝皮案震驚了整個濱河市臣樱,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌腮考,老刑警劉巖雇毫,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異踩蔚,居然都是意外死亡棚放,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進店門馅闽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來飘蚯,“玉大人,你說我怎么就攤上這事福也【种瑁” “怎么了?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵暴凑,是天一觀的道長峦甩。 經(jīng)常有香客問我,道長现喳,這世上最難降的妖魔是什么凯傲? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任犬辰,我火速辦了婚禮,結(jié)果婚禮上冰单,老公的妹妹穿的比我還像新娘忧风。我一直安慰自己,他們只是感情好球凰,可當我...
    茶點故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布狮腿。 她就那樣靜靜地躺著,像睡著了一般呕诉。 火紅的嫁衣襯著肌膚如雪缘厢。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天甩挫,我揣著相機與錄音贴硫,去河邊找鬼。 笑死伊者,一個胖子當著我的面吹牛英遭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播亦渗,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼挖诸,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了法精?” 一聲冷哼從身側(cè)響起多律,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎搂蜓,沒想到半個月后狼荞,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡帮碰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年相味,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片殉挽。...
    茶點故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡丰涉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出此再,到底是詐尸還是另有隱情昔搂,我是刑警寧澤,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布输拇,位于F島的核電站摘符,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜逛裤,卻給世界環(huán)境...
    茶點故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一瘩绒、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧带族,春花似錦锁荔、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至择克,卻和暖如春恬总,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背肚邢。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工壹堰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人骡湖。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓贱纠,卻偏偏與公主長得像,于是被迫代替她去往敵國和親响蕴。 傳聞我的和親對象是個殘疾皇子谆焊,可洞房花燭夜當晚...
    茶點故事閱讀 45,675評論 2 359

推薦閱讀更多精彩內(nèi)容