for...of循环在遍历Set时,如何正确添加元素?

简介: for...of循环在遍历Set时,如何正确添加元素?

在使用 for...of 循环遍历 Set 时添加元素需要格外谨慎,因为直接在遍历过程中修改 Set 的结构可能导致迭代器状态异常(如无限循环或跳过元素)。以下是安全添加元素的方法及注意事项:

一、错误示例:直接在循环中添加元素

const set = new Set([1, 2, 3]);
for (const num of set) {
   
  set.add(num + 1); // 错误:可能导致无限循环或异常
  console.log(num);
}
// 输出: 1, 2, 3(部分浏览器可能陷入无限循环)

问题原因
添加元素会改变 Set 的内部结构,导致迭代器无法正确跟踪元素位置,可能引发不可预测的行为。

二、安全方法:先完成遍历,再添加元素

核心思路:将添加逻辑与遍历逻辑分离,避免同时操作。

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

// 第一步:先遍历处理
for (const num of set) {
   
  console.log(num); // 输出: 1, 2, 3
}

// 第二步:遍历结束后添加元素
set.add(4);
set.add(5);

console.log([...set]); // 输出: [1, 2, 3, 4, 5]

三、使用临时数组存储待添加元素

步骤

  1. 遍历 Set 并记录需要添加的元素到临时数组。
  2. 遍历结束后,批量添加临时数组中的元素。
    ```javascript
    const set = new Set([1, 2, 3]);
    const toAdd = [];

// 遍历并收集待添加元素
for (const num of set) {
if (num > 1) {
toAdd.push(num + 10); // 例如:2→12,3→13
}
}

// 批量添加
toAdd.forEach(val => set.add(val));

console.log([...set]); // 输出: [1, 2, 3, 12, 13]



### **四、转换为数组后遍历并操作原 Set**
**步骤**:  
1. 将 Set 转换为数组(创建副本)。  
2. 遍历数组,向原 Set 中添加元素(此时遍历的是副本,不影响原 Set 的迭代状态)。  
```javascript
const set = new Set([1, 2, 3]);

[...set].forEach(num => {
  set.add(num * 10); // 向原 Set 添加元素
  console.log(num);  // 遍历的是数组副本,不受添加操作影响
});

console.log([...set]); // 输出: [1, 2, 3, 10, 20, 30]

五、注意事项与最佳实践

  1. 绝对避免遍历与修改同时进行
    任何在 for...of 循环中直接添加元素的操作都可能引发异常,必须分离遍历和修改逻辑。

  2. 临时存储的必要性

    • 若添加逻辑依赖遍历过程中的数据(如根据当前元素计算新元素),需先用临时数组存储待添加项,再批量操作。
  3. 性能考量

    • 转换为数组(方法四)会产生额外内存开销,若 Set 较大,优先使用临时数组收集(方法三)。
  4. 特殊场景:无限循环风险
    若添加的元素与原 Set 中的元素存在包含关系(如添加 numSet([num])),可能导致无限循环,需严格控制添加逻辑。

六、总结:安全添加的核心原则

  1. 逻辑分离:遍历阶段仅负责“读”操作,添加阶段仅负责“写”操作。
  2. 使用副本:通过数组副本或临时变量避免直接修改原 Set 的结构。
  3. 批量操作:收集所有待添加元素后,一次性批量添加,减少对迭代器的影响。

遵循以上原则,可在不破坏遍历逻辑的前提下安全地向 Set 中添加元素,避免因异步操作或状态异常导致的程序错误。

相关文章
|
13天前
|
存储 安全 JavaScript
如何使用Set的add()方法添加元素?
如何使用Set的add()方法添加元素?
146 58
|
13天前
|
存储 安全 JavaScript
如何在不影响遍历的情况下从Set中删除元素?
如何在不影响遍历的情况下从Set中删除元素?
116 58
|
13天前
|
存储 安全
for...of循环遍历Set时,如何删除元素?
for...of循环遍历Set时,如何删除元素?
108 57
|
13天前
|
存储 JavaScript 前端开发
for...of循环在遍历Set和Map时的注意事项有哪些?
for...of循环在遍历Set和Map时的注意事项有哪些?
34 0
|
3月前
|
Web App开发 存储 前端开发
别再用双层遍历循环来做新旧数组对比,寻找新增元素了!使用array.includes和Set来提升代码可读性
这类问题的重点在于能不能突破基础思路,突破基础思路是从程序员入门变成中级甚至高级的第一步,如果所有需求都通过最基础的业务逻辑来做,是得不到成长的。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
7月前
|
Java
那些与Java Set擦肩而过的重复元素,都经历了什么?
在Java的世界里,Set如同一位浪漫而坚定的恋人,只对独一无二的元素情有独钟。重复元素虽屡遭拒绝,但通过反思和成长,最终变得独特,赢得了Set的认可。示例代码展示了这一过程,揭示了成长与独特性的浪漫故事。
50 4
|
7月前
|
存储 Java 开发者
在 Java 中,如何遍历一个 Set 集合?
【10月更文挑战第30天】开发者可以根据具体的需求和代码风格选择合适的遍历方式。增强for循环简洁直观,适用于大多数简单的遍历场景;迭代器则更加灵活,可在遍历过程中进行更多复杂的操作;而Lambda表达式和`forEach`方法则提供了一种更简洁的函数式编程风格的遍历方式。
|
7月前
|
存储 Java
判断一个元素是否在 Java 中的 Set 集合中
【10月更文挑战第30天】使用`contains()`方法可以方便快捷地判断一个元素是否在Java中的`Set`集合中,但对于自定义对象,需要注意重写`equals()`方法以确保正确的判断结果,同时根据具体的性能需求选择合适的`Set`实现类。
|
7月前
|
存储 算法 Java
为什么Java Set如此“挑剔”,连重复元素都容不下?
在Java的集合框架中,Set是一个独特的接口,它严格要求元素不重复,适用于需要唯一性约束的场景。Set通过内部数据结构(如哈希表或红黑树)和算法(如哈希值和equals()方法)实现这一特性,自动过滤重复元素,简化处理逻辑。示例代码展示了Set如何自动忽略重复元素。
61 1
|
3月前
|
编译器 C++ 容器
【c++丨STL】基于红黑树模拟实现set和map(附源码)
本文基于红黑树的实现,模拟了STL中的`set`和`map`容器。通过封装同一棵红黑树并进行适配修改,实现了两种容器的功能。主要步骤包括:1) 修改红黑树节点结构以支持不同数据类型;2) 使用仿函数适配键值比较逻辑;3) 实现双向迭代器支持遍历操作;4) 封装`insert`、`find`等接口,并为`map`实现`operator[]`。最终,通过测试代码验证了功能的正确性。此实现减少了代码冗余,展示了模板与仿函数的强大灵活性。
99 2
下一篇
oss创建bucket
OSZAR »