set集合
一、set集合
一直以来,JS只能使用数组和对象来保存多个数据,缺乏像其他语言那样拥有丰富的集合类型。因此,ES6新增了两种集合类型(set 和 map),用于在不同的场景中发挥作用。
set用于存放不重复的数据
1.创建set集合
new Set(); //创建一个没有任何内容的set集合
new Set(iterable); //创建一个具有初始内容的set集合,内容来自于可迭代对象每一次迭代的结果
const s1 = new Set();
console.log(s1);
const s2 = new Set("asdfasfasf");//不会出现重复
console.log(s2);

2.set集合后续操作
add(数据): 添加一个数据到set集合末尾,如果数据已存在,则不进行任何操作
- set使用Object.is的方式判断两个数据是否相同,但是,针对+0和-0,set认为是相等
has(数据): 判断set中是否存在对应的数据
delete(数据):删除匹配的数据,返回是否删除成功
clear():清空整个set集合
size: 获取set集合中的元素数量,只读属性,无法重新赋值
const s1 = new Set();
s1.add(1);
s1.add(2);
s1.add(3);
s1.add(1); //无效
s1.add(+0);
s1.add(-0); //无效
console.log(s1);
console.log(s1.has(3));
console.log("总数为:", s1.size);
s1.delete(2);
console.log(s1);
s1.clear();
console.log(s1);

3.与数组进行相互转换
const arr = [45, 7, 2, 2, 34, 46, 6, 57, 8, 55, 6, 46];
const result = [...new Set(arr)];
console.log(result);
const str = "asf23sdfgsdgfsafasdfasfasfasfsafsagfdsfg";
const s = [...new Set(str)].join("");
console.log(s);

4.遍历
- 使用for-of循环
- 使用set中的实例方法forEach
注意:set集合中不存在下标,因此forEach中的回调的第二个参数和第一个参数是一致的,均表示set中的每一项
const s1 = new Set();
s1.add(1);
s1.add(2);
s1.add(3);
s1.add(1); //无效
s1.add(+0);
s1.add(-0); //无效
// for (const item of s1) {
// console.log(item)
// };
s1.forEach((item, index, s) => {
console.log(item, index, s);
});

3.set集合应用
// 两个数组的并集、交集、差集 (不能出现重复项),得到的结果是一个新数组
const arr1 = [33, 22, 55, 33, 11, 33, 5];
const arr2 = [22, 55, 77, 88, 88, 99, 99];
// const result = [...new Set(arr1.concat(arr2))];
console.log("并集", [...new Set([...arr1, ...arr2])]);

const cross = [...new Set(arr1)].filter(item => arr2.indexOf(item) >= 0);
console.log("交集", cross);

// 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出现之前,我们使用的是对象的方式来存储键值对,键是属性名,值是属性值。
使用对象存储有以下问题:
- 键名只能是字符串
- 获取数据的数量不方便
- 键名容易跟原型上的名称冲突
1.创建map
new Map(); //创建一个空的map
new Map(iterable); //创建一个具有初始内容的map,初始内容来自于可迭代对象每一次迭代的结果,但是,它要求每一次迭代的结果必须是一个长度为2的数组,数组第一项表示键,数组的第二项表示值
const mp1 = new Map([["a", 3], ["b", 4], ["c", 5]]);
console.log(mp1);

2.后续操作
size:只读属性,获取当前map中键的数量
set(键, 值):设置一个键值对,键和值可以是任何类型
- 如果键不存在,则添加一项
- 如果键已存在,则修改它的值
- 比较键的方式和set相同(+0=-0)
get(键): 根据一个键得到对应的值
has(键):判断某个键是否存在
delete(键):删除指定的键
clear(): 清空map
const mp1 = new Map([["a", 3], ["b", 4], ["c", 5]]);
console.log(mp1);
const obj = {};
mp1.set(obj, 6456);
mp1.set("a", "abc");
mp1.set(obj, 111);
console.log(mp1);
console.log("总数:", mp1.size);
console.log("get('a')", mp1.get("a"));
console.log("has('a')", mp1.has("a"));

3.和数组互相转换
const mp = new Map([
["a", 3],
["c", 10],
["b", 4],
["c", 5]
]);
const result = [...mp];
console.log(result);

4.遍历
for-of,每次迭代得到的是一个长度为2的数组
forEach,通过回调函数遍历
- 参数1:每一项的值
- 参数2:每一项的键
- 参数3:map本身
for (const [key, value] of mp) {
console.log(key, value)
};
mp.forEach((value, key, mp) => {
console.log(value, key, mp)
});

三、WeakSet 和 WeakMap
1.WeakSet
使用该集合,可以实现和set一样的功能,不同的是:
- 它内部存储的对象地址不会影响垃圾回收
- 只能添加对象
- 不能遍历(不是可迭代的对象)、没有size属性、没有forEach方法
let obj = {
name: "yj",
age: 18
};
const set = new WeakSet();
set.add(obj);
obj = null;
console.log(set);//已经被清理

let obj = {
name: "yj",
age: 18
};
const set = new WeakSet();
set.add(obj);
obj = null;
console.log(set);

2. WeakMap
类似于map的集合,不同的是:
- 它的键存储的地址不会影响垃圾回收
- 它的键只能是对象
- 不能遍历(不是可迭代的对象)、没有size属性、没有forEach方法
const wmap = new WeakMap();
let lis = document.querySelectorAll("li");
for (const li of lis) {
wmap.set(li, {
id: li.innerHTML,
name: `姓名${li.innerHTML}`
});
}
lis[0].remove();
lis = null;//要清楚所有能找到li[0]的对象
console.log(wmap);

本文深入解析ES6中新增的set、map、WeakSet和WeakMap集合类型,涵盖创建、操作、转换及应用,助您掌握高效数据处理技巧。

803

被折叠的 条评论
为什么被折叠?



