I recently heard about Facebook's Immutable.js library (https://github.com/facebook/immutable-js). I am confused about the following from their documentation:
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
How is filter called only twice, map once?
Immutable push is super fastjs is about 100x faster than push of native javascript . Note that when pushing an element to an immutable. js list, the list is not modified. A new list is returned with the element appended to it: this is how immutable collections work.
Seq is immutable — Once a Seq is created, it cannot be changed, appended to, rearranged or otherwise modified.
Working with immutable objects A pure function has two properties that make it unique: The value it returns is dependent on the input passed. The returned value will not change as long as the inputs do not change. It does not change things outside of its scope.
js provides many Persistent Immutable data structures including: List , Stack , Map , OrderedMap , Set , OrderedSet and Record .
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());
At the end, we get called the filter function two times and the mapper function only once
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With