【Set 和 Map 数据结构】
什么是 Set?
Set 是一系列无序、没有重复值的数据集合。
数组是一系列有序(下标索引)的数据集合。
1 2 3 4 5 6 7 8 9 const s = new Set ();s.add (1 ); s.add (2 ); s.add (1 ); console .log (s);
Set 实例的方法和属性
add 方法
1 2 3 4 5 const s = new Set ();s.add (0 ); s.add (1 ).add (2 ).add (2 ).add (3 ); console .log (s);
has 方法
1 2 3 4 5 const s = new Set ();s.add (0 ); s.add (1 ).add (2 ).add (2 ).add (3 ); console .log (s.has (1 )); console .log (s.has (4 ));
delete 方法
1 2 3 4 5 6 7 const s = new Set ();s.add (0 ); s.add (1 ).add (2 ).add (2 ).add (3 ); s.delete (2 ); s.delete (4 ); console .log (s);
clear 方法
1 2 3 4 5 const s = new Set ();s.add (0 ); s.add (1 ).add (2 ).add (2 ).add (3 ); s.clear (); console .log (s);
forEach 方法
作用:用于遍历 Set 的(按照成员添加进集合的顺序遍历)。
forEach 方法可以接受两个参数,第一个是:回调函数,第二个是:指定回调函数的 this 指向。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 const s = new Set ();s.add (0 ); s.add (1 ).add (2 ).add (2 ).add (3 ); s.forEach (function (value, key, set ) { console .log (value, key, set === s); console .log (this ); });
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 const s = new Set ();s.add (0 ); s.add (1 ).add (2 ).add (2 ).add (3 ); s.forEach (function (value, key, set ) { console .log (value, key, set === s); console .log (this ); }, document );
size 属性
1 2 3 4 5 const s = new Set ();s.add (0 ); s.add (1 ).add (2 ).add (2 ).add (3 ); console .log (s.size );
Set 构造函数的参数
数组
字符串、arguments、NodeList、Set 等
【数组】
1 2 const s = new Set ([1 , 2 , 1 ]);console .log (s);
【字符串】
1 console .log (new Set ('hiii' ));
【arguments】
1 2 3 4 function func ( ) { console .log (new Set (arguments )); } func (1 , 2 , 1 );
【NodeList】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > Title</title > </head > <body > <p > 1</p > <p > 2</p > <p > 3</p > <script > console .log (new Set (document .querySelectorAll ('P' ))); </script > </body > </html >
【Set】
1 2 3 4 const s = new Set ([1 , 2 , 1 ]);console .log (new Set (s)); console .log (s);
Set 注意事项
【Set 如何判断重复】
1 2 3 4 const s = new Set ();s.add ({}).add ({}); console .log ({} === {}); console .log (s);
【什么时候使用 Set】
数组或字符串需要去重时
不需要通过下标访问,只需要遍历时
为了使用 Set 提供的方法和属性时
Set 的应用
【数组去重】
1 2 3 const s = new Set ([1 , 2 , 1 ]);console .log (s); console .log ([...s]);
【字符串去重】
1 2 3 const s = new Set ('abbacbd' );console .log (s); console .log ([...s].join ('' ));
【存放 DOM 元素】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > Title</title > </head > <body > <p > 1</p > <p > 2</p > <p > 3</p > <script > const s = new Set (document .querySelectorAll ('p' )); s.forEach (function (elem ) { elem.style .color = 'red' ; }); </script > </body > </html >
【遍历】
数组的map
和filter
方法也可以间接用于 Set 了。
1 2 3 4 5 6 7 let set = new Set ([1 , 2 , 3 ]);set = new Set ([...set].map (x => x * 2 )); let set = new Set ([1 , 2 , 3 , 4 , 5 ]);set = new Set ([...set].filter (x => (x % 2 ) == 0 ));
因此使用 Set 可以很容易地实现并集(Union)、交集(Intersect)和差集(Difference)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 let a = new Set ([1 , 2 , 3 ]);let b = new Set ([4 , 3 , 2 ]);let union = new Set ([...a, ...b]);let intersect = new Set ([...a].filter (x => b.has (x)));let difference = new Set ([...a].filter (x => !b.has (x)));
什么是 Map?
Map 可以理解为:“映射”。
Map 和 对象 都是键值对的集合。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 const person = { name : 'alex' , age : 18 }; const m = new Map ();m.set ('name' , 'alex' ); m.set ('age' , 18 ); console .log (m); const m = new Map ();m.set (true , 'true' ); m.set ({}, 'object' ); m.set (new Set ([1 , 2 ]), 'set' ); m.set (undefined , 'undefined' ); console .log (m);
Map 实例的方法和属性
set 方法
set
方法设置键名key
对应的键值为value
,然后返回整个 Map 结构。如果key
已经有值,则键值会被更新,否则就新生成该键。
1 2 3 4 5 const m = new Map ();m.set ('edition' , 6 ) m.set (262 , 'standard' ) m.set (undefined , 'nah' )
set
方法返回的是当前的Map
对象,因此可以采用链式写法。
1 2 3 4 let map = new Map () .set (1 , 'a' ) .set (2 , 'b' ) .set (3 , 'c' );
get 方法
get
方法读取key
对应的键值,如果找不到key
,返回undefined
。
1 2 3 4 5 6 const m = new Map ();const hello = function ( ) {console .log ('hello' );};m.set (hello, 'Hello ES6!' ) m.get (hello)
has 方法
has
方法返回一个布尔值,表示某个键是否在当前 Map 对象之中。
1 2 3 4 5 6 7 8 9 10 const m = new Map ();m.set ('edition' , 6 ); m.set (262 , 'standard' ); m.set (undefined , 'nah' ); m.has ('edition' ) m.has ('years' ) m.has (262 ) m.has (undefined )
delete 方法
delete
方法删除某个键,返回true
。如果删除失败,返回false
。
1 2 3 4 5 6 const m = new Map ();m.set (undefined , 'nah' ); m.has (undefined ) m.delete (undefined ) m.has (undefined )
clear 方法
clear
方法清除所有成员,没有返回值。
1 2 3 4 5 6 7 let map = new Map ();map.set ('foo' , true ); map.set ('bar' , false ); map.size map.clear () map.size
forEach 方法
1 2 3 m.forEach (function (value, key, map ) { console .log (this ); }, document );
size 属性
size
属性返回 Map 结构的成员总数。
1 2 3 4 5 const map = new Map ();map.set ('foo' , true ); map.set ('bar' , false ); map.size
Map 构造函数的参数
【二维数组】
1 2 3 4 5 console .log (new Map ([ ['name' , 'alex' ], ['age' , 18 ] ]));
【Set、Map】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 const s = new Set ([ ['name' , 'alex' ], ['age' , 18 ] ]); console .log (new Map (s));console .log (s);const m = new Map ([ ['name' , 'alex' ], ['age' , 18 ] ]); console .log (m);const m2 = new Map (m);console .log (m2, m2 === m);
Map 注意事项
【Map 如何判断键名是否相同】
在 Set 中遇到重复的值直接去掉后者,而 Map 中遇到重复的键值则是后面的覆盖前面的。
基本遵循严格相等(===)
Map 中 NaN 也是等于 NaN
【什么时候使用 Map】
如果只是需要键值对结构
需要字符串以外的值做键
对象一般用在模拟实体上
Map 的应用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > Title</title > </head > <body > <p > 1</p > <p > 2</p > <p > 3</p > <script > const [p1, p2, p3] = document .querySelectorAll ('p' ); const m = new Map ([ [p1, { color : 'red' , backgroundColor : 'yellow' , fontSize : '40px' }], [p2, { color : 'green' , backgroundColor : 'pink' , fontSize : '40px' }], [p3, { color : 'blue' , backgroundColor : 'orange' , fontSize : '40px' }] ]); m.forEach ((propObj, elem ) => { for (const p in propObj) { elem.style [p] = propObj[p]; } }); </script > </body > </html >
运算符的扩展
Promise对象