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