ES6中的Set数据结构
Set
是 ES6 中新增的数据结构,用于存储不重复的值,允许存储任何类型的唯一值。Set
的核心特点是值唯一性,类似数学中的集合。
常用方法
1. add(value)
添加值到Set
中,如果值已存在则不会添加。
const set = new Set();
set.add(1); // Set {1}
2. delete(value)
删除指定值,返回布尔值,表示是否删除成功。
set.delete(1); // true
3. has(value)
检查值是否存在于Set
中,返回布尔值。
set.has(1); // false
4. clear()
清空整个Set
。
set.clear(); // Set {}
5. size
返回Set
中的元素数量。
set.size; // 0
6. forEach(callback)
遍历Set
,为每个值执行一次提供的回调函数。
let mySet = new Set([1, 2, 3, 4, 5]);
mySet.forEach(function(value, key) {
console.log('value: ' + value + ', key: ' + key);
});
7. 迭代器方法
keys()
和values()
: 返回包含集合中元素的迭代器(Set
的键和值相同)。entries()
: 返回[value, value]
格式的迭代器,适用于Map
接口的兼容。for...of
: 遍历Set
中的每个值。
let mySet = new Set([1, 2, 3, 4, 5]);
// 使用 .values()
for (let value of mySet.values()) {
console.log(value);
}
// 使用 .keys(),与 .values() 相同
for (let key of mySet.keys()) {
console.log(key);
}
// 使用 .entries()
for (let entry of mySet.entries()) {
console.log(entry); // 每个 entry 是一个 [value, value] 的数组
}
// 使用 for...of 循环来迭代其值
for (let value of mySet) {
console.log(value);
}
使用场景
1. 数组去重
利用Set
的唯一性快速去重。
const arr = [1, 2, 2, 3];
const uniqueArr = [...new Set(arr)]; // [1, 2, 3]
2. 数据集合处理
- 交集、并集、差集等操作可以通过
Set
简洁实现。
const setA = new Set([1, 2, 3]);
const setB = new Set([3, 4, 5]);
// 交集
const intersection = new Set([...setA].filter(x => setB.has(x))); // Set {3}
// 并集
const union = new Set([...setA, ...setB]); // Set {1, 2, 3, 4, 5}
// 差集
const difference = new Set([...setA].filter(x => !setB.has(x))); // Set {1, 2}
3. 集合判定
检查一个集合是否包含特定值或操作两个集合之间的关系,如交集或子集操作。
检查集合是否包含特定值
使用 Set
的 has()
方法来检查集合中是否存在某个值。
let mySet = new Set([1, 2, 3, 4, 5]);
if (mySet.has(3)) {
console.log("集合包含值 3");
} else {
console.log("集合不包含值 3");
}
计算两个集合的交集
可以通过 filter()
方法结合 Set.prototype.has
来找出两个集合的交集。
let setA = new Set([1, 2, 3, 4, 5]);
let setB = new Set([4, 5, 6, 7, 8]);
let intersection = new Set([...setA].filter(x => setB.has(x)));
console.log(intersection); // 输出 Set { 4, 5 }
判断一个集合是否为另一个集合的子集
可以利用 every()
方法来确定一个集合是否是另一个集合的子集。
function isSubset(setA, setB) {
return [...setA].every(element => setB.has(element));
}
let setX = new Set([1, 2]);
let setY = new Set([1, 2, 3, 4]);
console.log(isSubset(setX, setY)); // 输出 true
计算两个集合的并集
合并两个集合可以简单地使用 add()
方法或者利用扩展运算符。
let union = new Set([...setA, ...setB]);
console.log(union); // 输出 Set { 1, 2, 3, 4, 5, 6, 7, 8 }
计算两个集合的差集
计算两个集合的差集(即 A 中有而 B 中没有的元素),可以使用 filter()
方法。
let difference = new Set([...setA].filter(x => !setB.has(x)));
console.log(difference); // 输出 Set { 1, 2, 3 }
计算两个集合的对称差集
对称差集是指属于 A 或 B 之一但不属于两者都有的元素集合。
let symmetricDifference = new Set(
[...setA].filter(x => !setB.has(x)).concat([...setB].filter(x => !setA.has(x)))
);
console.log(symmetricDifference); // 输出 Set { 1, 2, 3, 6, 7, 8 }
4. 性能优化
在ES6中,Set
对象可以用来提高某些操作的性能,特别是在需要去除重复项、快速查找以及进行集合操作的场景下。以下是几种使用 Set
进行性能优化的方法:
去除数组中的重复项
当需要从一个数组中去除重复的元素时,使用 Set
可以非常高效,因为它会自动保证元素的唯一性。
let arr = [1, 2, 2, 3, 4, 4, 5];
let uniqueArr = [...new Set(arr)];
console.log(uniqueArr); // 输出 [1, 2, 3, 4, 5]
快速成员查找
由于 Set
的内部实现通常是基于哈希表的,因此 Set
的 has
方法可以提供接近 O(1) 的查找性能,这比在数组中使用 indexOf
或者 includes
方法要快得多。
let mySet = new Set([1, 2, 3, 4, 5]);
console.log(mySet.has(3)); // 输出 true
console.log(mySet.has(6)); // 输出 false
集合操作
使用 Set
可以更容易地实现集合的交集、并集、差集等操作,并且性能通常优于其他方式,尤其是当集合很大时。
并集(Union)
将两个集合的所有元素合并到一个新的集合中。
let setA = new Set([1, 2, 3]);
let setB = new Set([3, 4, 5]);
let union = new Set([...setA, ...setB]);
console.log(union); // 输出 Set { 1, 2, 3, 4, 5 }
交集(Intersection)
找出同时存在于两个集合中的元素。
let setA = new Set([1, 2, 3, 4, 5]);
let setB = new Set([4, 5, 6, 7, 8]);
let intersection = new Set([...setA].filter(x => setB.has(x)));
console.log(intersection); // 输出 Set { 4, 5 }
差集(Difference)
找出一个集合中有而另一个集合中没有的元素。
let setA = new Set([1, 2, 3, 4, 5]);
let setB = new Set([4, 5, 6, 7, 8]);
let difference = new Set([...setA].filter(x => !setB.has(x)));
console.log(difference); // 输出 Set { 1, 2, 3 }
存储唯一对象
如果需要存储一组唯一的对象(比如用户ID),可以将对象的唯一标识作为字符串存储在 Set
中,这样可以避免存储重复的对象。
let users = [
{ id: 'alice', name: 'Alice' },
{ id: 'bob', name: 'Bob' },
{ id: 'alice', name: 'Alice' } // 重复项
];
let uniqueUsersIds = new Set(users.map(user => user.id));
console.log(uniqueUsersIds); // 输出 Set { 'alice', 'bob' }
总结
Set
是处理唯一性问题、集合操作以及优化性能的有力工具,适合用于集合操作、数据去重、快速查找等场景。
使用 Set
可以有效地提升代码性能,尤其是在处理大量数据时,利用 Set
的特性和方法可以简化逻辑并提高运行效率。不过,需要注意的是,虽然 Set
在很多情况下提供了优秀的性能表现,但在某些特定场景下,可能还需要考虑其他数据结构或者算法来进一步优化。