2013-05-06 5 views
18

Я включил флагов Chrome для экспериментальных функций ECMAscript 6, один из которых - Set. Насколько я понимаю, детали Set в целом согласованы спецификаторами.Итерация над элементами набора

создать набор a и добавить строку 'Hello'

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

но как я итерацию по элементам a?

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

дает "SyntaxError: Illegal let декларация за пределами расширенного режима"

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

дает "SyntaxError: Неожиданный идентификатор"

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

дает Undefined

Можно ли итерацию через набор в Chrome 26?

+2

[Выглядит как для] (http: //kangax.github.io/es5-compat-table/es6) поддерживается только в Firefox ... –

+0

[Как реализовать набор в JavaScript] (http://www.javascriptexamples.org/2011/01/17/how-to- реализация-a-set-in-javascript /) – NullPointerException

+0

вы можете использовать это: http://jsclass.jcoglan.com/set.html –

ответ

2

of Оператор doesn't appear to be currently supported in Chrome. Кажется, что поддерживают только версии FireFox с 13 по 18. Также кажется, что ни один из браузеров фактически не поддерживает Set, хотя на странице действительно говорится, что некоторые из тестов представляют собой существование, а не полную функциональность или согласованность. Так может быть, что Set частично реализовано в Chrome.

4

Даже если синтаксический сахар для итерации еще не реализован, возможно, вы все равно можете использовать итераторы.

http://www.2ality.com/2012/06/for-of-ff13.html объясняет

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.

Таким образом, вы должны быть в состоянии перебрать множество используя

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 
} 

Вы также можете определить функциональную версию для & hellip; походит

function forOf(collection, f) { 
    // jQuery.each calling convention for f. 
    var applyToElement = f.bind(/* this */ collection, /* index */ void 0); 
    for (var it = mySet.__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; } 
    } 
} 
+1

Спасибо. Впрочем, это немного смешно. – Randomblue

+3

@ Randomblue, да. Синтаксический сахар предназначен для блеска всего этого, но часто разные люди реализуют поддержку синтаксиса в парсере, чем реализуют библиотечный код, поэтому вы получаете выпуски с половиной функции. Когда это синтаксис, который отстает, вам просто нужно самому отбросить его, что требует увидеть, как производится колбаса. –

+0

В последнем Node v0.11.4 такого метода '__iterator__' нет. – Randomblue

4

По спецификации от MDN, Set имеет values метод:

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

Таким образом, для перебора значений, я хотел бы сделать:

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

Когда итерация будет остановлена? Согласно документам, StopIteration будет выброшен. Использование исключения для остановки итерации - это ужасное решение. –

+0

Если вы имеете в виду документ MDN об Iterator, я не уверен, что их документ по-прежнему точен, у них также есть предупреждение на странице. Итератор прекратит движение, как только он достигнет конца. – bizi

0

@bizi's answer близко, но это не сработало для меня. Это работает на Firefox:

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

Очень простой способ превратить набор в массив первых:

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

... а затем просто использовать простой цикл.

+0

Кроме того, он имеет второй необязательный параметр, который является функцией отображения для вызова каждого элемента, то есть: a = Array.from (a, e => e.length) '. – Adamantium

Смежные вопросы