2014-09-16 12 views
5

Ich habe kürzlich über Facebooks Immutable.js-Bibliothek (https://github.com/facebook/immutable-js) gehört. Ich bin verwirrt über die folgenden aus ihrer Dokumentation:Immutable.js - Lazy Sequence

var oddSquares = Immutable.Sequence(1,2,3,4,5,6,7,8) 
    .filter(x => x % 2).map(x => x * x); 
console.log(oddSquares.last()); 

In this example, no intermediate arrays are ever created, filter is only called twice, and map is only called once 

Wie wird Filter nur zweimal aufgerufen, einmal zuordnen?

Antwort

12

Wegen der Logik der Karte und das Filter bezüglich lazy evaluation von Sequenzen

Karte

letzte() über eine zugeordnete Sequenz zurückkehren die letzte() der ursprünglichen Sequenz durch die Mapper-Funktion verarbeitet aufgerufen .

So zum Beispiel:

var mappedSequence = Immutable.Sequence(1,2,3,4,5,6,7,8).map(x => x * x); 
console.log(mappedSequence.last()); 

Will Ausgang 64 und Karte nennen wird nur einmal, denn das einzige, was sie tut, ist das letzte Element der ursprünglichen Sequenz erhalten (8) und auf x map = > x * x (was auf 64)

Filter

letzten() über eine gefilterte Sequenz genannt wird Rückwärts Fuß die Sequenz, bis sie einen Wert in der Sequenz findet, der den Kriterien entspricht. So zum Beispiel

var mappedSequence = Immutable.Sequence(1,2,3,4,5,6,7,8).filter(x => x % 2); 
console.log(mappedSequence.last()); 

ausgegeben 7 und Filter nennen nur zweimal, weil es den Filter aufrufen (x => x% 2) für 8 erste, gibt sie 0 für Javascript false bedeutet (so es sollte gefiltert werden), und dann die Filterfunktion erneut aufrufen, um 7% 2 = 1 für javascript zu erhalten und diesen Wert als letzten ohne Aufruf der Filterfunktion zurückzuliefern.

Als weiteres Beispiel helfen verstehen:

var mappedSequence = Immutable.Sequence(1,2,3,4,6,8).filter(x => x % 2); 
console.log(mappedSequence.last()); 

würde die Filterfunktion viermal nennen, einen für 8 (was falsch), ein für 6 (false wieder), ein für 4 (false wieder) und schließlich für 3 (was schließlich true)

zusammen

Ihr Beispiel beide Stücke Putting:

var oddSquares = Immutable.Sequence(1,2,3,4,5,6,7,8) 
    .filter(x => x % 2).map(x => x * x); 
console.log(oddSquares.last()); 
  1. Um den letzten() Wert der abgebildeten Sequenz zu erhalten, sie bekommen zuerst den letzten() Wert der gefilterten Sequenz
  2. Um den letzten() Wert der gefilterten Sequenz zu erhalten, ist es zunächst die letzten zu erhalten () Wert der ursprünglichen Sequenz (8) und bewerten Sie es erneut die Filterfunktion (x => x% 2), ruft es zum ersten Mal
  3. Seit 8% 2 = 0 ist es auf JS falsch und sollte gefiltert werden , so gehen wir zum nächsten Wert (7) und rufen Sie die Filterfunktion erneut mit diesem Wert
  4. 7% 2 = 1, es ist auf JS und sollte nicht gefiltert werden, also ist dies der letzte Wert der gefilterten Sequenz
  5. Wir haben den letzten Wert (7) von der zugeordneten Sequenz benötigt, so dass wir Mapper aufrufen Funktion (x => x * x) nur einmal-49 zu bekommen, um das Endergebnis

Am Ende haben wir die Filterfunktion zweimal und die Mapper-Funktion nur einmal

aufgerufen
+0

Fantastische Antwort, danke! –