js set(长文解析)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;演示链接: http://116.62.199.48:7070 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观
在 JavaScript 开发中,处理数据时常常会遇到“去重”和“唯一值管理”的需求。例如,统计用户浏览的唯一页面、记录不同类型的事件日志,或是管理购物车中的商品种类。此时,一种名为 Set 的内置数据结构便能发挥关键作用。本文将从基础概念出发,结合具体案例,深入解析 JS Set
的核心特性、操作方法及实际应用场景,帮助读者在项目中高效利用这一工具。
什么是 Set?
Set 是 JavaScript 中用于存储无序且不重复值的集合数据结构。与数组(Array)不同,Set 的每个元素都是唯一的,且插入顺序会被保留。可以将其想象为一个“不重复的购物车”——无论用户添加多少次同一商品,购物车中只会保留一份。
核心特性:
- 唯一性:Set 中的元素不可重复。
- 无序性:元素的存储顺序可能与插入顺序一致,但不保证严格遵循。
- 可迭代:支持
for...of
循环和迭代器方法。
Set 的应用场景
- 去重:快速从数组中移除重复项。
- 唯一值统计:例如统计用户点击的不同按钮数量。
- 集合运算:交集、并集、差集等操作(需结合其他方法实现)。
如何创建和操作 Set?
1. 创建 Set
通过 new Set()
构造函数或直接使用 Set
关键字初始化。
// 空 Set
const emptySet = new Set();
// 从数组创建 Set
const numbers = [1, 2, 2, 3, 4];
const uniqueNumbers = new Set(numbers);
console.log(uniqueNumbers); // Set {1, 2, 3, 4}
2. 添加元素:add() 方法
使用 add(value)
将元素加入 Set。若元素已存在,则无变化。
const fruits = new Set();
fruits.add("apple");
fruits.add("banana");
fruits.add("apple"); // 第二次添加会被忽略
console.log(fruits.size); // 输出 2
3. 检查元素:has() 方法
通过 has(value)
判断某个值是否存在于 Set 中。
console.log(fruits.has("banana")); // true
console.log(fruits.has("orange")); // false
4. 移除元素:delete() 方法
使用 delete(value)
移除指定元素。
fruits.delete("banana");
console.log(fruits); // Set {"apple"}
5. 清空 Set:clear() 方法
通过 clear()
删除所有元素。
fruits.clear();
console.log(fruits.size); // 0
6. 获取元素数量:size 属性
size
属性返回 Set 中元素的数量。
const colors = new Set(["red", "green", "blue"]);
console.log(colors.size); // 3
Set 的遍历与迭代
由于 Set 是可迭代对象,可以通过以下方式遍历:
1. for...of 循环
const letters = new Set(["a", "b", "c"]);
for (const letter of letters) {
console.log(letter); // 输出 "a", "b", "c"
}
2. 遍历器方法
- keys()、values()、entries():返回迭代器对象。
- forEach():对每个元素执行回调函数。
letters.forEach((value, key, set) => {
console.log(`Value: ${value}, Key: ${key}`);
});
// 输出:
// Value: a, Key: a
// Value: b, Key: b
// Value: c, Key: c
Set 的高级用法
1. 与数组的交互:去重与转换
Set 可以轻松解决数组去重问题:
const duplicatedArray = [5, 5, 6, 7, 7, 7];
const uniqueArray = [...new Set(duplicatedArray)];
console.log(uniqueArray); // [5, 6, 7]
2. 集合运算的实现
虽然 JavaScript 的原生 Set 不直接支持交集、并集等运算,但可通过手动实现:
并集(Union)
function union(setA, setB) {
const _union = new Set(setA);
for (const elem of setB) {
_union.add(elem);
}
return _union;
}
const set1 = new Set([1, 2]);
const set2 = new Set([3]);
console.log(union(set1, set2)); // Set {1, 2, 3}
交集(Intersection)
function intersection(setA, setB) {
const _intersection = new Set();
for (const elem of setA) {
if (setB.has(elem)) {
_intersection.add(elem);
}
}
return _intersection;
}
const set3 = new Set([1, 2, 3]);
const set4 = new Set([2, 3, 4]);
console.log(intersection(set3, set4)); // Set {2, 3}
3. 检测唯一性:验证数据合法性
在表单验证中,Set 可用于检查用户输入是否包含重复值:
function hasDuplicates(arr) {
return new Set(arr).size !== arr.length;
}
console.log(hasDuplicates([1, 2, 3])); // false
console.log(hasDuplicates([1, 2, 2])); // true
Set 与 Map 的对比
特性 | Set | Map |
---|---|---|
存储结构 | 单值集合(仅存储元素本身) | 键值对集合(Key-Value) |
唯一性 | 元素唯一 | 键唯一 |
遍历顺序 | 插入顺序 | 插入顺序 |
适用场景 | 去重、唯一值管理 | 关联数据存储(如用户 ID 与姓名) |
实战案例:统计网页访问路径
假设需要记录用户访问的不同页面路径,并统计唯一访问次数:
let pageViews = new Set();
function trackPage(path) {
pageViews.add(path);
console.log(`当前唯一路径数量:${pageViews.size}`);
}
// 模拟用户访问
trackPage("/home"); // 输出:1
trackPage("/about"); // 输出:2
trackPage("/home"); // 输出:2(重复路径不计数)
trackPage("/contact"); // 输出:3
性能与注意事项
1. 时间复杂度
- 添加/删除/查询:平均 O(1)(基于哈希表实现)。
- 遍历:O(n),取决于元素数量。
2. 注意事项
- 类型敏感:
"1"
和1
在 Set 中被视为不同元素。 - 不可变性:Set 的元素值可以是对象,但对象本身的变化不会影响 Set 的唯一性。
const objSet = new Set();
const obj1 = { name: "Alice" };
objSet.add(obj1);
obj1.name = "Bob"; // 对象属性变化,但 Set 中的引用未变
console.log(objSet.has(obj1)); // true
结论
通过本文的讲解,读者应已掌握 JS Set 的核心功能及使用场景。无论是基础的去重操作,还是进阶的集合运算,Set 都能提供简洁高效的解决方案。在实际开发中,合理利用 Set 可以显著减少代码复杂度,提升数据处理的可靠性。
对于希望进一步优化性能或实现复杂逻辑的开发者,建议结合 ES6 的其他特性(如 Map
、WeakSet
)或第三方库(如 Lodash 的集合方法)扩展功能。实践是掌握技术的最佳途径——尝试将 Set 应用到你的项目中,体验其带来的便利!