迭代集合元素

Ran*_*lue 39 javascript ecmascript-6

我已经打开了Chrome标志,用于实验性的ECMAscript 6功能,其中之一就是Set.据我了解,详细信息Set由规范编写者广泛认同.

我创建一个集合a并添加字符串'Hello'

a = Set();
a.add('Hello');
Run Code Online (Sandbox Code Playgroud)

但我如何迭代元素a

for(let i of a) { console.log(i); }
Run Code Online (Sandbox Code Playgroud)

给出"SyntaxError:let扩展模式外的非法声明"

for(var i of a) { console.log(i); }
Run Code Online (Sandbox Code Playgroud)

给出"SyntaxError:意外的标识符"

for(var i in a) { console.log(i); }
Run Code Online (Sandbox Code Playgroud)

Undefined

是否有可能在Chrome 26中迭代一组?

lus*_*chn 20

一种非常简单的方法是首先将Set转换为数组:

let a = new Set();
a.add('Hello');
a = Array.from(a);
Run Code Online (Sandbox Code Playgroud)

...然后只使用一个简单的for循环.

  • 此外,它还有第二个可选参数,它是一个调用每个元素的映射函数,即:“a = Array.from(a, e => e.length)”。 (2认同)

biz*_*izi 17

根据MDN的规范,Set有一个方法:

values()方法返回一个新的Iterator对象,该对象包含插入顺序中Set对象中每个元素的值.

所以,为了遍历这些值,我会这样做:

var s = new Set(['a1', 'a2'])
for (var it = s.values(), val= null; val=it.next().value; ) {
    console.log(val);
}
Run Code Online (Sandbox Code Playgroud)

  • 那么什么时候停止迭代呢?根据文档,StopIteration 会被抛出。使用异常来停止迭代是一个糟糕的解决方案。 (2认同)

Fra*_*nXh 16

我用的是这个forEach(..);功能.

  • 我不能因为我想从循环中调用异步函数的等待。 (3认同)
  • 这个问题/答案/sf/ask/2630367981/比我解释得更好。但基本上,foreach 在某种意义上会工作,但不是你期望的那样。foreach 不会等待并按顺序执行代码块。它并行地激发它们。也许这可能是您想要的,但它并不真正等同于 for 循环。 (2认同)

小智 10

您可以使用两种方法。 for...offorEach

let a = new Set();
a.add('Hello');

for(let key of a) console.log(key)

a.forEach(key => console.log(key))
Run Code Online (Sandbox Code Playgroud)


小智 8

您还可以使用扩展运算符将 a 转换Set为数组( 的替代方法Array.from(yourSet))。

const mySet = new Set();

mySet.add('a');
mySet.add('b')

const iterableSet = [...mySet];
// end up with: ['a', 'b']

// use any Array method on `iterableSet`
const lettersPlusSomething = iterableSet.map(letter => letter + ' something');
Run Code Online (Sandbox Code Playgroud)


jpt*_*er2 7

一个简单的函数方法就是使用forEach

const mySet = new Set([1, 2, 3])
mySet.forEach(a => { console.log(a) })
// 1 2 3
Run Code Online (Sandbox Code Playgroud)


Viv*_*ath 5

Chrome似乎不支持of操作员。似乎只有FireFox 13至18版本支持它。似乎也没有任何浏览器实际支持,尽管该页面确实说某些测试代表存在而不是全部功能或一致性。因此,可能部分是在Chrome中实现的。SetSet


Mik*_*uel 5

即使尚未实现迭代的语法糖,您仍然可以使用迭代器。

http://www.2ality.com/2012/06/for-of-ff13.html说明

特殊方法__iterator__返回一个迭代器对象。这样的对象有一个方法next(),要么返回当前迭代序列中的下一个元素,要么在StopIteration没有更多元素时抛出。

所以你应该能够使用

for (var it = mySet.__iterator__();;) {
  var element;
  try {
    element = it.next();
  } catch (ex) {
    if (ex instanceof StopIteration) {
      break;
    } else {
      throw ex;
    }
  }
  // Do something with element
}
Run Code Online (Sandbox Code Playgroud)

您还可以定义 for...of like 的功能版本

function forOf(collection, f) {
  // jQuery.each calling convention for f.
  var applyToElement = f.bind(/* this */ collection, /* index */ void 0);
  for (var it = collection.__iterator__();;) {
    var element;
    try {
      element = it.next();
    } catch (ex) {
      if (ex instanceof StopIteration) {
        break;
      } else {
        throw ex;
      }
    }

    // jQuery.each return convention.
    if (applyToElement(element) === false) { break; }
  }
}
Run Code Online (Sandbox Code Playgroud)

  • @Randomblue,是的。语法糖旨在掩盖所有这些,但通常不同的人在解析器中实现语法支持而不是实现库代码,因此您可以获得具有一半功能的版本。当它的语法滞后时,您只需要自己将其脱糖,这需要查看香肠是如何制作的。 (3认同)