Because of the logic of map and filter regarding lazy evaluation of sequences
map
last() called over a mapped sequence return the last() of the original sequence processed by the mapper function.
So for example:
var mappedSequence = Immutable.Sequence(1,2,3,4,5,6,7,8).map(x => x * x);
console.log(mappedSequence.last());
Will output 64 and will call map only once, because the only thing it does is get the last element of original sequence (8) and map it on x => x * x (resulting on 64)
filter
last() called over a filtered sequence, will reverse walk the sequence until it finds a value on sequnce matching the criteria. So, for example
var mappedSequence = Immutable.Sequence(1,2,3,4,5,6,7,8).filter(x => x % 2);
console.log(mappedSequence.last());
WIll output 7 and will call filter only twice, because it call the filter (x => x % 2) for 8 first, it returns 0 meaning false for javascript (so it should be filtered), and then call the filter function again to get 7 % 2 = 1 being true for javascript and returning that value as the last without calling filter functoin anymore.
As additional example to help understand:
var mappedSequence = Immutable.Sequence(1,2,3,4,6,8).filter(x => x % 2);
console.log(mappedSequence.last());
Would call the filter function four times, one for 8 (resulting false), one for 6 (false again), one for 4 (false again), and finally for 3 (finally resulting true)
Putting both pieces together
Your example:
var oddSquares = Immutable.Sequence(1,2,3,4,5,6,7,8)
.filter(x => x % 2).map(x => x * x);
console.log(oddSquares.last());
- To get the last() value of mapped sequence, it first get the last() value of filtered sequence
- To get the last() value of filtered sequence, it first get the last() value of original sequence (8) and evaluate it agains the filter function ( x => x % 2 ), calling it for first time
- Since 8 % 2 = 0, it is false on JS and should be filtered, so, we move to the next value (7) and call the filter function again with this value
- 7 % 2 = 1, it is true on JS and should NOT be filtered, so, this is the last value of the filtered sequence
- We have the last value (7) required by the mapped sequence, so we call mapper function (x => x * x) only one time to get 49, the final result
At the end, we get called the filter function two times and the mapper function only once