使用for..of进行迭代时删除Set中的元素是否安全? [英] Is it safe to delete elements in a Set while iterating with for..of?

查看:54
本文介绍了使用for..of进行迭代时删除Set中的元素是否安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否指定您可以在使用for..of进行迭代时删除Set实例中的任何元素,并且

Is it specified that you can delete any element in an instance of Set while iterating using for..of and that

  • 您不会在一个元素上重复多次
  • 除了删除的元素外,您不会错过迭代开始时集合中的其他任何元素

?

推荐答案

,最好在迭代时添加元素和删除元素到集合中.考虑了此用例,JavaScript 2015(ES6)支持此用例.它将保持一致状态.请注意,这也适用于使用forEach进行的枚举.

Yes, it is perfectly fine to add elements and remove elements to a set while iterating it. This use case was considered and is supported in JavaScript 2015 (ES6). It will leave it in a consistent state. Note this also applies to itearting with forEach.

集合迭代算法基本上看起来像这样:

The set iteration algorithm basically looks something like this:

Set position to 0
While position < calculateLength() // note it's calculated on each iteration
    return the element at set.entryList[position]

加法看起来像这样:

If element not in set
   Add element to the _end_ of the set

因此它不会干扰现有的迭代-他们会对其进行迭代.

So it does not interfere with existing iterations - they will iterate it.

删除看起来像这样:

Replace all elements with are equal to `element` with a special empty value

用一个空值代替它而不是删除它确保它不会弄乱迭代器的位置.

Replacing it with an empty value rather than deleting it ensures it will not mess up with iterators' positions.

这是%SetIteratorPrototype%.next中规范的相关部分:

Here is the relevant part of the specification from %SetIteratorPrototype%.next:

在索引小于条目的元素总数时重复. 每次评估此方法时,都必须重新确定元素的数量.

set迭代器继续逐个迭代条目.

The set iterator proceeds to iterate the entries one by one.

来自Set.prototype.add:

将值附加为条目的最后元素.

这可确保在将元素添加到列表时,它将在迭代完成之前进行迭代,因为它总是在条目列表中获得新的位置.因此,这将按照规范的要求进行工作.

This ensures that when adding elements to the list it will be iterated before the iteration completes since it always gets a new slot in the entries list. Thus this will work as the spec mandates.

关于删除:

将值为e 的条目元素替换为值为空的元素.

用一个空元素代替而不是删除它可以确保现有迭代器的迭代顺序不会消失或不顺序,并且它们将继续正确地迭代集合.

Replacing it with an empty element rather than removing it ensures that the iteration order of existing iterators will not get out or order and they will continue iterating the set correctly.

这是演示此功能的简短代码段

Here is a short code snippet that demonstrates this ability

var set = new Set([1]);
for(let item of set){
   if(item < 10) set.add(item+1);
   console.log(item);
}

哪个数字记录从1到10.这是一个不用于...的版本,今天您可以在浏览器中运行该版本:

Which logs the numbers 1 to 10. Here is a version not using for... of you can run in your browser today:

var set = new Set([1]);
for (var _i = set[Symbol.iterator](), next; !(next = _i.next()).done;) {
   var item = next.value;
   if (item < 10) set.add(item + 1);
   document.body.innerHTML += " " + item;
}

这篇关于使用for..of进行迭代时删除Set中的元素是否安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆