1. Set()构造函数
【概念】 Set 是 ES6 新增的数据结构,它类似于数组,但成员的值是唯一的,无重复值
Set本身是一个构造函数,需要通过 new 的方式创建实例,去生成Set数据结构
let set = new Set();
【参数】
-
给
Set添加值可以通过传参的方式传值,也可以通过调用原型上的add方法 -
参数是具备
iterator的接口的数据结构,包括数组、类数组
【特点】
- 值唯一,相等的值只会保留一个
- 类似于数组的结构
console.log(new Set([1, 2, 7, 7, 7]));
下面的例子:
var set = new Set(
[0, -0, undefined, undefined, null, null, 5, '5', true, 1, NaN, NaN, {}, {},[], []
])
console.log(set)
/*
数字 5 和字符串 '5' 不相等
空对象和空对象不相等
空数组和空数组不相等
*/
由此例子可以得出 Set中几个特殊值:
-
+0 与 -0 在存储判断唯一性的时候是恒等的,所以不重复
-
undefined与undefined是恒等的,所以不重复 -
NaN 与 NaN 是不恒等的,但是在
Set中认为NaN与NaN相等
1.1 操作当前数据结构的方法
1.add():添加
调用该方法返回的是 Set 结构本身, 当添加实例中已经存在的元素, set 不会进行处理添加
var set = new Set();
var x = {
id: 1
},
y = {
id: 2
};
set.add(x).add(y); // 添加值,返回的是Set结构本身,所以可以链式调用
set.add(x); // 两个 x 虽然都是对象,但是引用的地址值是一样的
// size 长度
console.log(set.size);
console.log(set);
2.delete():删除
删除元素本身, 返回布尔值, 代表删除与否
注意: 删除操作是实时的,具体看下面两段代码输出内容的差别
let set = new Set();
let x = {
id: 1,
},
y = {
id: 2,
};
set.add(x).add(y);
console.log(set.delete(y));
console.log(set.delete(y));
console.log(set);
let set = new Set();
let x = {
id: 1,
},
y = {
id: 2,
};
set.add(x).add(y);
console.log(set);
console.log(set.delete(y));
由此我们可以看出输出的
set集合中的值不因为先进行删除还是后进行删除而变化
3.has():是否有某个值
表示是否有某个值,返回布尔值,代表删除与否
let set = new Set();
let x = {
id: 1,
},
y = {
id: 2,
};
set.add(x).add(y);
console.log(set.has(x)); // true
4.clear():清除
清除所有成员,没有返回值(返回 undefined),与 delete一样,操作是实时的
以下两段代码:
let set = new Set();
let x = {
id: 1,
},
y = {
id: 2,
};
console.log(set.clear());
console.log(set);
let set = new Set();
let x = {
id: 1,
},
y = {
id: 2,
};
console.log(set);
console.log(set.clear());
1.2 迭代的方法
1.keys()、values()、entries()
-
keys():返回键 名 的遍历器。 -
values():返回键 值 的遍历器。 -
entries():返回键值 对 的遍历器。
【特点】
set没有键名 只有值,所以返回的 keys 和 values 是一样的,都是值
-
遍历
set本身,for of本质上是调用Set.prototype.values -
Set.prototype[Symbol.iterator] === Set.prototype.values;
let set = new Set(['a', 'b', 'c', 'd', 'e', 'f', 'g']);
console.log(set.keys());
console.log(set.values());
console.log(set.entries());
// set 没有键名 只有值,所以返回的keys和values是一样的,都是值
for (let i of set.keys()) {
console.log(i); // 返回一个键名的迭代器
}
for (let i of set.values()) {
console.log(i); // 返回一个键值的迭代器
}
for (let i of set.entries()) {
console.log(i); // 返回一个键值对的迭代器
}
// 遍历 set 本身
// for of 本质上是调用 Set.prototype.values
for (let i of set) {
console.log(i) // 输出 a b c d e f g
}
2.forEach
使用回调函数遍历每个成员,本质同数组的 forEach类似
【参数】 分别对应:
-
每个元素
-
索引
-
被遍历的数组
let set = new Set(['a', 'b', 'c', 'd', 'e', 'f', 'g']);
set.forEach((value, keys, arr) => {
console.log(value, keys, arr)
})
2. Set 常见用法
1. 利用set进行数组去重
拓展运算符能够展开具有迭代器接口的数据结构
let set = new Set(['a', 'b', 'c', 'd', 'e', 'f', 'g']);
// 可以利用set进行数组去重
console.log([...set]);
/*
通过 set 值的唯一性,将数组作为参数传入,再通过拓展运算符将梳理后的数组展开
*/
2. 结合map修改元素值
题目: 将传入数组中的元素成倍输出
思路:将 set 通过解构的方式变为数组,再去调用数组上的 map 方法
let set = new Set([1, 2, 3, 4, 5]);
console.log(set);
let set1 = new Set([...set].map((value) => value * 2));
console.log(set1);
3. 结合parseInt
var arr = [1, 2, 3, 4];
var arr1 = arr.map(parseInt);
console.log(arr1); // 输出 [1, NaN, NaN, NaN]
/*
这里parseInt会传入两个参数parseInt(item, index)
*/
// 相当于
var arr2 = arr.map((values, index) => console.log(values, index));
// 输出 1 0、2 1、3 2、4 3
let set = new Set([1, 2, 3, 4, 5, 6, 7]);
let set2 = new Set([
[...set].map(parseInt)
])
3. 结合filter
let set = new Set([1, 2, 3, 4, 5, 6, 7]);
let set2 = new Set([...set].filter((x) => {
return (x % 2) === 0
}));
console.log(set2);
3. 实现交集、并集、差集
let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2]);
// 并集
let union = new Set([...a, ...b]);
console.log(...[union]);
// 交集
let intersect = new Set([...a]).filter((x) => {
return b.has(x)
});
console.log(intersect);
// 差集
let difference = new Set([...a]).filter((x) => {
!b.has(x);
})
console.log(difference);
4. 映射出一个新的结构
let set = new Set([1, 2, 3]);
// 方式1 map
let set1 = new Set([...set].map(value => value * 2));
// 方式2 Array.from
let set2 = new Set(Array.from(set, value => value * 2))