2015-02-16 4 views
8

Wie können die neuen ES5-Array-Funktionen mit ES6-Generatoren korrekt verwendet werden? Muss ich das Iterable zuerst explizit in ein Array konvertieren, oder gibt es einen besseren Weg? Zum Beispiel:Verwenden von ES5-Array-Methoden mit ES6-Generatoren

function* range(low, high) { 
    var i = low; 
    while(i < high) 
     yield i++; 
} 

// Sum of numbers in range, doesn't work 
console.log(range(0, 10).reduce((x,y) => x + y)); 
+0

möglich Duplikat [Warum nicht Generatoren tun Support-Map()?] (https://StackOverflow.com/q/31232415/1048572) – Bergi

Antwort

8

Generatorfunktionen zurück Iterator Objekte. Die Iterator-API enthält keine Array-Methoden höherer Ordnung wie map, reduce usw., daher müssen Sie ein intermediäres Array erstellen (oder eine Bibliothek wie wu.js verwenden).

können Sie die spread operator verwenden knapp ein Array aus einem (endlichen) Iterator zu bauen:

var sum = [...range(0, 10)].reduce((e, i) => e + i) 
+0

Es funktioniert, ich fragte mich nur, ob es eine eingebaute Art und Weise des Umgangs damit, ohne ein Zwischen-Array (etwa zum Beispiel, wenn das erzeugte Array ziemlich groß wäre). Es scheint aber nicht so zu sein. – Lesleh

+0

Ich denke, es ist nicht direkt möglich, weil Iteratoren unbegrenzt sein können. Wie würdest du eine unendliche Sequenz reduzieren? – joews

+0

Yup, guter Punkt. wu.js sieht so aus, wie ich es brauche, also akzeptiere ich diese Antwort. – Lesleh

2

Da Array.from nicht zum aktuellen Zeitpunkt auf Chrome arbeiten, brauchte ich eine andere Möglichkeit, einen Iterator in ein Array zu konvertieren.

(obwohl natürlich kann man shim it with a polyfill)

function iterator2Array(iterator) { 
    var result = []; 
    for (var item in iterator) { 
     result.push(item) 
    } 
    return result; 
} 

Aus ähnlichen Gründen fügt ich eine „toArray“ den Prototyp einer Karte, so dass ich im Grunde einen Iterator in ein Array konvertieren, so dass Sie seine Verwendung funktionsorientierte Methoden; natürlich jedes Element des Arrays a [key, value] Tupel (genau wie in seiner Map.entries())

if (!Map.prototype.toArray) { 
    /** 
    * Transforms a map into an Array of 'tuples' [[key, value], ...] 
    */ 
    Map.prototype.toArray = function() { 
     var result = []; 

     for (var item of this) { 
      result.push(item); 
     } 

     return result; 
    } 
} 

var m = new Map([[0, 0], ['a', 'A']]); 
m.toArray() 

Dann werden Sie es als ein Array verwenden können - denken Sie daran, die [key, value] Ansatz though!

m.toArray().map(
    function(item, index, array) { 
     var key = item[0], 
     value = item[1]; 
     console.log(key + ": " + value); 
     return value; 
}); 

Damit werden die Werte der Karte (ok nicht superuseful natürlich!) Zurückkehren

Wenn Sie eine standartisierte suchen Schleife bevorzugen:

var i = iterator.entries(), 
    result = [], 
    value; 
while (value = i.next().value) { 
    result.push(value); 
}