2014-09-16 12 views
5

Niedawno słyszałem o bibliotece Immutable.js na Facebooku (https://github.com/facebook/immutable-js). Jestem zdezorientowany z następującej dokumentacji:Immutable.js - leniwa sekwencja

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 

Jak filtr jest wywoływany tylko dwa razy, mapować raz?

Odpowiedz

12

Ponieważ logiki mapie i filtr dotyczące lazy oceny sekwencji

map

ostatni() wywołane przez odwzorowanym sekwencji powrotu ostatni() z oryginalnej sekwencji przetwarzane przez funkcję elementu odwzorowującego .

Tak na przykład:

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

wyjście będzie 64 i wezwie mapę tylko raz, bo jedyne co robi to dostać ostatni element oryginalnej sekwencji (8) i mapować go od x = > x * x (otrzymany w 64)

filtr

ostatni() wywołane przez filtrowany sekwencji będzie odwrotnej odległości sekwencję, dopóki nie znajdzie wartości w sequnce pasującej do kryteriów. Tak więc, na przykład

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

wyjściowy będzie 7 i wywoła filtr tylko dwukrotnie, ponieważ wywołać filtr (X => x% 2) przez 8 pierwszy zwraca 0 oznacza fałszywe JavaScript (tak, że powinny być filtrowane), a następnie wywołać funkcję filtru ponownie, aby uzyskać poprawność 7% 2 = 1 dla języka javascript i zwrócenie tej wartości jako ostatniej bez funkcji wywołującego filtru.

Jako kolejny przykład, aby pomóc zrozumieć:

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

wymagałyby funkcji filtru czterokrotnie, jeden do 8 (w wyniku fałsz), po jednym dla 6 (fałszywego ponownie), po jednym dla 4 (fałsz ponownie), a na końcu do 3 (wreszcie wynikające true)

Umieszczenie obu części razem

Twój przykład:

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. Aby uzyskać ostatni() wartość zmapowanych kolejności, najpierw się ostatnią() wartości przefiltrowanej sekwencji
  2. Aby uzyskać ostatni() wartości przefiltrowanej kolejności, najpierw ostatni () wartość oryginalnej sekwencji (8) i oceń ją przed funkcją filtrującą (x => x% 2), wywołując ją po raz pierwszy
  3. Od 8% 2 = 0, jest nieprawdziwe na JS i powinno być filtrowane , więc przechodzimy do następnej wartości (7) i wywołujemy funkcję filtra ponownie o tej wartości
  4. 7% 2 = 1, jest prawdą w JS i NIE powinien być filtrowany, więc jest to ostatnia wartość przefiltrowanej sekwencji
  5. Mamy ostatnią wartość (7) wymaganą przez odwzorowaną sekwencję, więc wywołujemy program odwzorowujący funkcja (x => x * x) tylko jeden raz dostać 49, ostateczny wynik

na koniec, mamy zwany filtr funkcyjne dwa razy a funkcja mapowania tylko raz

+0

Fantastyczna odpowiedź, dzięki! –