🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[toc] > 一直以来,JS只能使用数组和对象来保存多个数据,缺乏像其他语言那样拥有丰富的集合类型。因此,ES6新增了两种集合类型(set 和 map),用于在不同的场景中发挥作用。 ### set集合 **set用于存放不重复的数据** 1. 如何创建set集合 ```js new Set(); //创建一个没有任何内容的set集合 new Set(iterable); //创建一个具有初始内容的set集合,内容来自于可迭代对象每一次迭代的结果 //例如: const s1 = new Set(); const s2 = new Set([1,2,3,4,5,5,5,6]); console.log(s1); //输出一个空的Set集合,Set(0) {} console.log(s2); //s2在初始化set集合时传入了一个数组(数组为可迭代对象)做为s2的初始值。又因为set集合中存放的数据不能重复,所以自动将数组中重复的数据忽略掉,得到的结果为Set(6) {1,2,3,4,5,6} ``` 除了数组外,set集合可以将任何可迭代对象做为初始化参数(包括字符串)。 >由此可见,set集合是一个将数组、字符串等可迭代对象去重的一个比较好的方法。 2. 如何对set集合进行后续操作 - add(数据): 添加一个数据到set集合末尾,如果数据已存在,则不进行任何操作 - set使用Object.is的方式判断两个数据是否相同,但是,针对+0和-0,set认为是相等 - has(数据): 判断set中是否存在对应的数据 - delete(数据):删除匹配的数据,返回是否删除成功 - clear():清空整个set集合 - size: 获取set集合中的元素数量,只读属性,无法重新赋值 3. 如何与数组进行相互转换 ```js const s = new Set([1,2,3,4,4,5,6,7,4,5,6,7]); // set本身也是一个可迭代对象,每次迭代的结果就是每一项的值 const arr = [...s]; // 上面的代码可以简写成如下方式,直接获得一个去重后的数组 const arr = [...new Set([1,2,3,4,4,5,6,7,4,5,6,7])]; ``` >字符串去重也可以先将字符串做为参数创建一个set集合,获得一个去重后的数组,然后使用join("")方法拼接成字符串。 4. 如何遍历 1). 使用for-of循环 2). 使用set中的实例方法forEach 注意:set集合中不存在下标,因此forEach中的回调的第二个参数和第一个参数是一致的,均表示set中的每一项 5. 应用案例: 利用set实现求两个数组的并集、交集、差集,结果返回一个新的数组 ```js // 定义两个数组 const arr1 = [33, 22, 55, 33, 11, 33, 5]; const arr2 = [22, 55, 77, 88, 88, 99, 99]; //求并集方法一: console.log("并集", [...new Set(arr1.concat(arr2))]); //求并集方法二: console.log("并集", [...new Set([...arr1, ...arr2])]); //求交集,定义变量cross是为了简化求差集 const cross = [...new Set(arr1)].filter(item => arr2.indexOf(item) >= 0); console.log("交集", cross) //求差集方法一:(判断条件,arr1有的且arr2没有的值返回,或者arr2有的且arr1没有的值返回) console.log("差集", [...new Set([...arr1, ...arr2])].filter(item => arr1.indexOf(item) >= 0 && arr2.indexOf(item) < 0 || arr2.indexOf(item) >= 0 && arr1.indexOf(item) < 0)) //求差集方法二:(利用交集的变量,返回并集中不含交集的部分) console.log("差集", [...new Set([...arr1, ...arr2])].filter(item => cross.indexOf(item) < 0)) ``` ### map集合 键值对(key value pair)数据集合的特点:键不可重复 map集合专门用于存储多个键值对数据。 在map出现之前,我们使用的是对象的方式来存储键值对,键是属性名,值是属性值。 使用对象存储有以下问题: - 键名只能是字符串 - 获取数据的数量不方便 - 键名容易跟原型上的名称冲突 针对以上问题,ES6提供了map集合,用来弥补用对象存储数据的一些不足。 在实际开发中,可根据数据的结构来选择是使用对象存储还是map存储。 对象存储适用于属性较固定,且缺一不可的情况。例如:员工信息中的姓名,姓别,年龄等信息均需完整,缺少一项该员工信息就不完整。 map集合适用于属性数量不固定,动态增减属性不会对集合的使用造成影响。例如:一个网络请求,集合中包含的属性都是不固定的,但均可以发送请求。 1. 如何创建map ```js new Map(); //创建一个空的map new Map(iterable); //创建一个具有初始内容的map,初始内容来自于可迭代对象每一次迭代的结果,但是,它要求每一次迭代的结果必须是一个长度为2的数组,数组第一项表示键,数组的第二项表示值 ``` 2. 如何进行后续操作 - size:只读属性,获取当前map中键的数量 - set(键, 值):设置一个键值对,键和值可以是任何类型 - 如果键不存在,则添加一项 - 如果键已存在,则修改它的值 - 比较键的方式和set相同 - get(键): 根据一个键得到对应的值 - has(键):判断某个键是否存在 - delete(键):删除指定的键 - clear(): 清空map 3. 和数组互相转换 和set一样 4. 遍历 - for-of,每次迭代得到的是一个长度为2的数组 - forEach,通过回调函数遍历 - 参数1:每一项的值 - 参数2:每一项的键 - 参数3:map本身 ### [扩展]WeakSet 和 WeakMap #### WeakSet 使用该集合,可以实现和set一样的功能,不同的是: 1. **它内部存储的对象地址不会影响垃圾回收** 2. 只能添加对象 3. 不能遍历(不是可迭代的对象)、没有size属性、没有forEach方法 #### WeakMap 类似于map的集合,不同的是: 1. **它的键存储的地址不会影响垃圾回收** 2. 它的键只能是对象 3. 不能遍历(不是可迭代的对象)、没有size属性、没有forEach方法