Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lazily map, filter, reduce, etc. in JavaScript

Array#map, Array#filter create a new array and hence effectively iterating over the array (or creating new array).

Whereas in rust, python, java, c#, etc. such expression chain will iterate only once.

In most cases this is irrelevant and we do not have to care about that. However in some cases the performance hit could be a deal breaker to leverage the function api of the Array class.

How do you mitigate this? So you have any preference on a library enabling lazy evaluation for functional expression?

like image 850
Nas Avatar asked May 24 '26 15:05

Nas


1 Answers

As of ECMAScript 2025 you can use iterator helpers.

Example:

const res =  Array(100000000)
             .keys()                  // 0, 1, 2, 3, 4, 5, 6, 7, ...
             .map(x => 3*x)           // 0, 3, 6, 9, 12, 15, 18, 21, ...
             .filter(x => x % 5 == 1) // 6, 21, 36, 51, 66, ...
             .take(4)                 // 6, 21, 36, 51
             .reduce((a, b) => a + b) // Sum: 114
             
console.log(res);

This has the lazy behaviour: even though it looks like it, there is at no time an array with 100000000 elements. The initial array is sparse, and just has a length property and no entries. It is also the only array in this expression. The keys method returns an iterator, which only gets consumed indirectly and lazily by the chain of iterator functions. It is the final reduce call (which is also an iterator method) that initiates the consumption of values from the chained iterators (the "pipe"). As take(4) limits the need for values, only a limited number of values are consumed from the keys() iterator and those that follow it, so that this expression finishes quickly with a result.

like image 57
trincot Avatar answered May 26 '26 03:05

trincot



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!