2013-05-06 14 views
18

Mam włączoną flagę Chrome dla eksperymentalnych funkcji ECMAscript 6, z których jedną jest Set. Jak rozumiem, szczegóły Set są szeroko uzgodnione przez twórców specyfikacji.Iteracja nad zestawami elementów

utworzyć zestaw a i dodać ciąg 'Hello'

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

ale w jaki sposób iteracyjne nad elementami a?

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

daje "SyntaxError: Illegal let zgłoszenia poza rozszerzony tryb"

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

daje "SyntaxError: Nieoczekiwany identyfikator"

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

daje Undefined

Czy jest możliwe iteracyjne ponad zestawem w Chrome 26?

+2

[Wygląda na] (http: //kangax.github.io/es5-compat-table/es6) jest obecnie obsługiwany tylko w Firefoksie ... –

+0

[Jak zaimplementować zestaw w JavaScript] (http://www.javascriptexamples.org/2011/01/17/how-to- implement-a-set-in-javascript /) – NullPointerException

+0

możesz użyć tego: http://jsclass.jcoglan.com/set.html –

Odpowiedz

2

Operator of . Wygląda na to, że obsługują go tylko wersje FireFox od 13 do 18. Wygląda również na to, że żadna z przeglądarek nie obsługuje w rzeczywistości Set, chociaż strona mówi, że niektóre testy reprezentują istnienie, a nie pełną funkcjonalność lub spójność. Być może część Set jest częściowo zaimplementowana w Chrome.

4

Nawet jeśli cukier syntaktyczny dla iteracji nie został jeszcze zaimplementowany, prawdopodobnie nadal można używać iteratorów.

http://www.2ality.com/2012/06/for-of-ff13.html wyjaśnia

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.

więc powinieneś być w stanie iteracyjne nad zestawu używając

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 
} 

Można również zdefiniować funkcjonalną wersję dla & hellip; jakby

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

Dzięki. Ale jest trochę obrzydliwie. – Randomblue

+3

@Randomblue, Yeah. Cukru syntaktycznego ma się nad tym wszystkim pochwalić, ale często różni ludzie implementują obsługę składni w parserze, niż implementują kod biblioteki, aby uzyskać wersje z połową funkcji. Kiedy jest to składnia, która opóźnia się, musisz sam ją wyrzucić, co wymaga zobaczenia, jak powstaje kiełbasa. –

+0

Nie ma takiej metody "__iterator__" w najnowszym węźle v0.11.4. – Randomblue

4

Po spec od MDN, Set ma values metody:

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

Tak więc, na iterację wartości, zrobiłbym:

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

Po zatrzymaniu iteracji? Według doktorów, StopIteracja byłaby rzucona. Użycie wyjątku do zatrzymania iteracji jest okropnym rozwiązaniem. –

+0

Jeśli chodzi o dokument MDN dotyczący Iteratora, nie jestem pewien, czy ich dokument jest nadal dokładny, mają również Ostrzeżenie na stronie. Iterator przestanie przesuwać się, gdy dojdzie do końca. – bizi

0

@bizi's answer jest blisko, ale to nie działa dla mnie. To działało na 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

bardzo prosty sposób to, aby włączyć zestaw do tablicy pierwszy:

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

... a potem po prostu użyć prosty dla pętli.

+0

Ma również drugi, opcjonalny parametr, który jest funkcją odwzorowania do wywoływania każdego elementu, tj .: 'a = Array.from (a, e => e.length)'. – Adamantium

Powiązane problemy