在集合元素上迭代

我已经为实验性的 ECMAscript 6特性打开了 Chrome 标志,其中之一就是 Set。据我所知,Set的细节已经得到了规范编写者的广泛认可。

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

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

但是如何迭代 a的元素呢?

for(let i of a) { console.log(i); }

给出“ SyntaxError: 扩展模式之外的非法 let声明”

for(var i of a) { console.log(i); }

给出“ SyntaxError: 意外标识符”

for(var i in a) { console.log(i); }

给出 Undefined

在 Chrome26中可以迭代一个集合吗?

106279 次浏览

The of operator doesn't appear to be currently supported in Chrome. It seems that only FireFox versions 13 through 18 support it. It also appears that none of the browsers actually support Set although the page does say that some of the tests represent existence and not full functionality or coherence. So it might be that Set is partially implemented in Chrome.

Even if the syntactic sugar for iteration hasn't been implemented yet, you can probably still use iterators.

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

The special method __iterator__ returns an iterator object. Such an object has a method next() that either returns the next element in the current iteration sequence or throws StopIteration if there are no more elements.

So you should be able to iterate over the set using

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
}

You can also define a functional version of 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; }
}
}

I use the forEach(..); function. (documentation)

Upon the spec from MDN, Set has a values method:

The values() method returns a new Iterator object that contains the values for each element in the Set object in insertion order.

So, for iterate through the values, I would do:

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

@bizi's answer is close but it did not work for me. This worked on Firefox:

var s= new Set([1,2]),
it = s.values();
for (var val= it.next().value; val=it.next().value;) {
console.log("set: "+val);
}

A very easy way is to turn the Set into an Array first:

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

...and then just use a simple for loop.

Be aware that Array.from is not supported in IE11.

this worked for me

mySet.forEach(async(item) =>{
await doSomething(item)
})

There are two methods you can use. for...of and forEach

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


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


a.forEach(key => console.log(key))
let set = new Set();
set.add(1);
set.add(2);


// This will be an array now, now you can loop normally.
console.log([...set]);

A simple functional approach is to just use forEach

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

You can also use the spread operator to convert a Set into an array (an alternative to 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');