目录
一、Set集合
Set类似于数组,但是成员的值都是唯一的,没有重复的值。Set 本身是一个构造函数,用来生成 Set 数据结构。Set 构造函数可以接受一个数组(或者具有 iterable 接口的其他数据结构)作为参数,用来初始化。
1、创建一个Set数据结构
不设置参数,创建一个空的set集合
let set = new Set()
console.log(set);//Set(0) {}
也可以接受一个数组(或者具有 iterable 接口的其他数据结构)作为参数
let set = new Set([1,2,3])
console.log(set);//Set(3) { 1, 2, 3 }
2、添加元素
添加元素使用add方法
注意:
使用add方法添加基本数据类型成员 会做自动去重;
使用add方法添加引用数据类型成员 会全部添加,因为引用地址不相同,不算重复值。
let set = new Set()
set.add('zhangsan');
set.add('zhangsan');//无法添加成功,因为值重复了
set.add('lisi');
set.add('wangwu');
set.add([1,2,3]);
set.add([1,2,3]);//两个[1,2,3]都能添加成功,因为引用地址不同
console.log(set);//Set(5) { 'zhangsan', 'lisi', 'wangwu', [ 1, 2, 3 ], [ 1, 2, 3 ] }
3、删除元素
删除元素,使用delete方法:
let set = new Set(['zhangsan','lisi','wangwu',[1,2,3]])
set.delete('zhangsan')//可以删除成功
set.delete([1,2,3])//无法删除成功
console.log(set);//Set(3) { 'lisi', 'wangwu', [ 1, 2, 3 ] }
注意:当我们要删除引用数据类型的成员时,需要传入引用地址,而不能传值。
let set = new Set(['zhangsan','lisi','wangwu'])
let arr = [1,2,3]
set.add(arr)
set.delete(arr)
console.log(set);//Set(3) { 'zhangsan', 'lisi', 'wangwu' }
4、查看set长度
查看set长度,使用size属性:
let set = new Set(['zhangsan','lisi','wangwu'])
console.log(set.size);//3
5、遍历set成员
5.1 keys()、values()、entries()
Set有keys()、values()、entries()方法,这三个方法都返回一个迭代器对象,可以使用for-of来遍历它们的返回值:
遍历set.keys()得到set的key值,遍历set.values()得到set的value值,遍历set.entries()得到key和value值组成的数组。
注意:Set集合的key值和value值是一样的。
let set = new Set(['zhangsan',[1,2,3]])
console.log(set.keys());//[Set Iterator] { 'zhangsan', [ 1, 2, 3 ] }
console.log(set.values());//[Set Iterator] { 'zhangsan', [ 1, 2, 3 ] }
console.log(set.entries()); //[Set Entries] {[ 'zhangsan', 'zhangsan' ], [ [ 1, 2, 3 ], [ 1, 2, 3 ] ]}
for(let k of set.keys()){
console.log(k); //zhangsan [ 1, 2, 3 ]
}
5.2 forEach
forEach接收一个回调函数作为参数,回调函数有三个参数,分别表示key值,value值以及set集合本身,返回值为undefined
let set = new Set(['zhangsan', [1, 2, 3]])
let res = set.forEach((key, value, set) => {
console.log(key, value, set);
/*
打印结果:
zhangsan zhangsan Set(2) { 'zhangsan', [ 1, 2, 3 ] }
[ 1, 2, 3 ] [ 1, 2, 3 ] Set(2) { 'zhangsan', [ 1, 2, 3 ] }
*/
});
console.log(res);//undefined
6、判断有没有某个成员
判断有没有某个成员,使用has方法,返回结果为true或false。
注意:判断引用值时,也需要传入引用地址,而不能传值,否则会返回false
let set = new Set(['zhangsan', [1, 2, 3]])
let arr = [7,8,9]
set.add(arr)
console.log(set.has('zhangsan'));//true
console.log(set.has([1,2,3]));//false
console.log(set.has(arr));//true
console.log(set.has('hello'));//false
7、清空set集合
清空set集合使用clear方法,无参,返回清空后set
let set = new Set(['zhangsan', [1, 2, 3]])
set.clear();
console.log(set);//Set(0) {}
8、应用——数组去重
var arr = [1, 'yezi', 2, 1, 3, 4, 2, 'yezi', 4]
var set=new Set(arr);
console.log(set); //{ 1, 'yezi', 2, 3, 4 }
//将返回值转成数组
console.log(Array.from(set)); //[ 1, 'yezi', 2, 3, 4 ]
//或者使用 console.log([...set]);
二、Map集合
Map类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object 结构提供了“字符串—值”的对应,Map结构提供了“值—值”的对应,是一种更完善的 Hash 结构实现。如果你需要“键值对”的数据结构,Map 比 Object 更合适。Map 可以接受一个数组作为参数。该数组的成员是一个个表示键值对的数组。
1、创建一个map集合
let map = new Map()
console.log(map); //Map(0) {}
传参需要传入一个键值对组成的二维数组:
let map = new Map([['name','zhangsan'],[1,'hello']])
console.log(map); //Map(2) { 'name' => 'zhangsan', 1 => 'hello' }
2、添加map成员
添加map成员,使用set方法:第一个参数是key值,第二个参数是value值。
let map = new Map([['name','zhangsan'],[1,'hello']])
map.set('age',19)
console.log(map);//Map(3) { 'name' => 'zhangsan', 1 => 'hello', 'age' => 19 }
3、删除map成员
删除map成员,使用delete方法,参数为key值。
delete 可以直接删除基本数据类型得键,删除引用数据类型需要删除引用地址
let map = new Map([['name','zhangsan'],[1,'hello']])
map.delete(1)
console.log(map);//Map(1) { 'name' => 'zhangsan' }
4、获取map属性值
获取map属性值,使用get方法,传入key值作为参数:
let map = new Map([['name','zhangsan'],[1,'hello']])
console.log(map.get('name'));//zhangsan
5、遍历map成员
5.1 keys()、values()、entries()
Map有keys()、values()、entries()方法,这三个方法都返回一个迭代器对象,可以使用for-of来遍历它们的返回值:
遍历map.keys()得到map的key值,遍历map.values()得到map的value值,遍历map.entries()得到key和value值组成的数组。
let map = new Map([['name','zhangsan'],[1,'hello']])
console.log(map.keys());//[Map Iterator] { 'name', 1 }
console.log(map.values());//[Map Iterator] { 'zhangsan', 'hello' }
console.log(map.entries());//[Map Entries] { [ 'name', 'zhangsan' ], [ 1, 'hello' ] }
for(let k of map.keys()){
console.log(k);//name 1
}
5.2 forEach
forEach接收一个回调函数作为参数,回调函数有三个参数,分别表示value值,key值以及map集合本身,返回值为undefined
let map = new Map([['name','zhangsan'],[1,'hello']])
let res = map.forEach((value, key, map) => {
console.log(value, key, map);
/*
打印结果:
zhangsan name Map(2) { 'name' => 'zhangsan', 1 => 'hello' }
hello 1 Map(2) { 'name' => 'zhangsan', 1 => 'hello' }
*/
});
console.log(res);//undefined
6、Map和Object的区别
Map | Object | |
---|---|---|
意外的键 | Map 默认情况不包含任何键。只包含显式插入的键。 | 一个 Object 有一个原型, 原型链上的键名有可能和你自己在对象上的设置的键名产生冲突。 |
键的类型 | 一个 Map的键可以是任意值,包括函数、对象或任意基本类型。 | 一个Object 的键必须是一个 String 或是Symbol。 |
键的顺序 | Map 中的 key 是有序的。因此,当迭代的时候,一个 Map 对象以插入的顺序返回键值。 | 一个 Object 的键是无序的。注意:自ECMAScript 2015规范以来,对象确实保留了字符串和Symbol键的创建顺序; 因此,在只有字符串键的对象上进行迭代将按插入顺序产生键。 |
Size | Map 的键值对个数可以轻易地通过size 属性获取 | Object 的键值对个数只能手动计算 |
迭代 | Map 是 iterable 的,所以可以直接被迭代。 | 迭代一个Object需要以某种方式获取它的键然后才能迭代。 |
性能 | 在频繁增删键值对的场景下表现更好。 | 在频繁添加和删除键值对的场景下未作出优化。 |