set js(一文讲透)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...点击查看项目介绍 ;
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;

截止目前, 星球 内专栏累计输出 82w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2900+ 小伙伴加入学习 ,欢迎点击围观

在JavaScript开发中,处理数据的唯一性高效性是常见的需求。例如,用户提交的表单可能包含重复的选项,需要快速去重;游戏中的角色属性可能需要动态管理且避免重复值。这时,ES6引入的Set数据结构(即“set js”)便能大显身手。本文将从基础概念到实战案例,逐步解析如何利用Set提升代码质量与性能,帮助开发者在实际项目中灵活应用这一工具。


Set的基本概念与特性

什么是Set?

Set是ES6新增的一种数据结构,用于存储无序且唯一的值集合。其核心特性包括:

  1. 唯一性:每个元素只能出现一次,重复添加的值会被自动忽略。
  2. 无序性:元素的插入顺序不固定,但迭代时会按照插入顺序返回。
  3. 动态性:支持增删改查操作,并可与其他数据结构(如Array)无缝协作。

比喻:可以将Set想象为一个“不重复的购物车”,当你尝试放入已有的商品时,系统会直接忽略,而不会重复添加。

如何创建和使用Set?

通过new Set()初始化一个空的Set,或传入可迭代对象(如数组)初始化:

// 创建空Set  
const mySet = new Set();  

// 通过数组初始化  
const fruits = new Set(["Apple", "Banana", "Orange"]);  

// 添加元素  
mySet.add("Apple");  
mySet.add("Banana");  
mySet.add("Banana"); // 重复值会被忽略  

console.log(mySet.size); // 输出:2  

Set的核心方法与属性

方法/属性作用描述示例代码
add(value)向Set中添加元素,并返回Set本身mySet.add("Grape");
delete(value)移除指定元素,返回布尔值(是否成功)mySet.delete("Banana");
has(value)检查元素是否存在,返回布尔值mySet.has("Apple");
clear()清空Set中的所有元素mySet.clear();
size返回Set中元素的数量mySet.size;

Set的核心方法详解

1. 添加与删除元素

添加元素:add()

通过add()方法可向Set中添加任意类型的数据,包括数字、字符串、对象等:

const mixedSet = new Set();  
mixedSet.add(42);          // 数字  
mixedSet.add("Hello");     // 字符串  
mixedSet.add({ name: "Alice" }); // 对象  

console.log(mixedSet.size); // 输出:3  

删除元素:delete()

delete()方法会尝试移除指定值,若成功返回true,否则返回false。注意,若元素不存在,也不会报错:

const mySet = new Set(["Apple", "Banana"]);  
console.log(mySet.delete("Banana")); // true  
console.log(mySet.delete("Cherry")); // false  

2. 检查元素存在性

has()方法

通过has()方法可以快速判断某个值是否存在于Set中,时间复杂度为O(1)(常数时间),比数组的includes()方法更高效:

const fruits = new Set(["Apple", "Banana"]);  
console.log(fruits.has("Apple")); // true  
console.log(fruits.has("Orange")); // false  

3. 遍历与转换

迭代Set的元素

可以通过for...of循环或forEach()方法遍历Set中的元素:

const mySet = new Set([1, 2, 3]);  

// 使用for...of循环  
for (const value of mySet) {  
  console.log(value); // 输出1,2,3  
}  

// 使用forEach  
mySet.forEach((value) => console.log(value));  

转换为数组

利用扩展运算符...Array.from()可将Set转为数组:

const mySet = new Set([1, 2, 3]);  
const arr = [...mySet]; // [1,2,3]  
const arr2 = Array.from(mySet); // 同样结果  

Set在实际开发中的应用场景

场景1:快速去重

在表单提交或API响应中,数据可能包含重复项。通过Set可轻松实现去重:

// 原始数组包含重复值  
const inputValues = ["red", "blue", "red", "green"];  

// 转换为Set并返回数组  
const uniqueValues = [...new Set(inputValues)];  
console.log(uniqueValues); // ["red", "blue", "green"]  

场景2:统计唯一元素数量

无需遍历数组即可直接获取唯一值的数量:

const numbers = [1, 2, 3, 2, 4, 3];  
const uniqueCount = new Set(numbers).size; // 4  

场景3:管理唯一标识符

在需要唯一ID的场景(如生成唯一用户Token)中,Set可确保无重复:

let uniqueTokens = new Set();  
function generateToken() {  
  let token = Math.random().toString(36).substr(2, 5);  
  while (uniqueTokens.has(token)) {  
    token = Math.random().toString(36).substr(2, 5);  
  }  
  uniqueTokens.add(token);  
  return token;  
}  

Set与Array的对比与协作

对比表格:Set vs Array

功能需求Set实现方式Array实现方式
去重new Set(array)array.filter((v,i,a)=>a.indexOf(v)===i)
检查元素存在set.has(value)array.includes(value)
效率O(1)(常数时间)O(n)(线性时间)

Set与Array的协作

通过Set可以优化数组操作,例如合并两个数组并去重:

const array1 = [1, 2, 3];  
const array2 = [3, 4, 5];  

// 使用Set合并并去重  
const merged = [...new Set([...array1, ...array2])]; // [1,2,3,4,5]  

进阶技巧:结合其他ES6特性优化代码

1. 结合Map实现对象去重

若需对对象数组去重(如根据某个属性值),可结合MapSet

const users = [  
  { id: 1, name: "Alice" },  
  { id: 2, name: "Bob" },  
  { id: 1, name: "Alice" }  
];  

// 根据id去重  
const uniqueUsers = Array.from(  
  users.reduce((map, user) => map.set(user.id, user), new Map())  
).map(item => item[1]); // [第一个Alice, Bob]  

2. 使用生成器函数处理大数据

当处理海量数据时,可通过生成器函数逐批处理,避免内存溢出:

function* processLargeData(data) {  
  const seen = new Set();  
  for (const item of data) {  
    if (!seen.has(item)) {  
      seen.add(item);  
      yield item; // 逐个处理唯一值  
    }  
  }  
}  

// 示例用法  
const largeArray = [/* ... */];  
for (const uniqueItem of processLargeData(largeArray)) {  
  // 处理每个唯一项  
}  

结论:Set JS在现代Web开发中的重要性

通过本文的讲解,我们看到Set数据结构在JavaScript中解决了多个痛点:它以O(1)的时间复杂度处理元素的增删查,简化了去重逻辑,且与Array等其他结构协作灵活。无论是前端表单处理、后端API响应优化,还是大数据场景的高效计算,Set都能提供简洁高效的解决方案。

对于开发者而言,掌握Set的使用不仅能够提升代码质量,还能在面对复杂数据需求时游刃有余。建议在日常开发中优先考虑使用Set替代手动去重的数组操作,从而减少冗余代码,提升项目性能。

希望本文能帮助你在JavaScript的进阶之路上更进一步!

最新发布