Immutable.js — ленивая последовательность


person tldr    schedule 16.09.2014    source источник


Ответы (1)


Из-за логики карты и фильтра в отношении ленивой оценки последовательностей

карта

last(), вызванный по сопоставленной последовательности, возвращает last() исходной последовательности, обработанной функцией сопоставления.

Так, например:

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

Выведет 64 и вызовет map только один раз, потому что единственное, что он делает, это получает последний элемент исходной последовательности (8) и сопоставляет его с x => x * x (результатом будет 64)

фильтр

last(), вызываемый для отфильтрованной последовательности, будет проходить в обратном порядке по последовательности, пока не найдет значение последовательности, соответствующее критериям. Так, например

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

Выведет 7 и вызовет фильтр только дважды, потому что он сначала вызывает фильтр (x => x % 2) для 8, он возвращает 0, что означает ложь для javascript (поэтому его следует отфильтровать), и затем снова вызовите функцию фильтра, чтобы получить 7 % 2 = 1, являющееся истинным для javascript, и вернуть это значение как последнее, не вызывая больше функцию фильтра.

В качестве дополнительного примера, чтобы помочь понять:

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

Будет вызывать функцию фильтра четыре раза, один раз для 8 (в результате получается false), один для 6 (снова false), один для 4 (снова false) и, наконец, для 3 (в итоге получается true)

Соединяем обе части вместе

Ваш пример:

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. Чтобы получить значение last() сопоставленной последовательности, сначала нужно получить значение last() отфильтрованной последовательности.
  2. Чтобы получить значение last() отфильтрованной последовательности, он сначала получает значение last() исходной последовательности (8) и снова оценивает его функцией фильтра ( x => x % 2 ), вызывая ее в первый раз< /сильный>
  3. Поскольку 8 % 2 = 0, на JS оно ложно и должно быть отфильтровано, поэтому мы переходим к следующему значению (7) и вызываем функцию фильтра еще раз с этим значением
  4. 7 % 2 = 1, это верно для JS и НЕ ДОЛЖНО фильтроваться, поэтому это последнее значение отфильтрованной последовательности
  5. У нас есть последнее значение (7), требуемое сопоставленной последовательностью, поэтому мы вызываем функцию сопоставления (x => x * x) только один раз, чтобы получить 49, окончательный результат

В конце мы вызываем функцию фильтра два раза, а функцию отображения только один раз.

person dseminara    schedule 16.09.2014