Iterator Helpers

Before ECMAScript 2025, only Array (and a handful of other built-ins) had convenient methods like .map(), .filter(), and .reduce(); a plain Iterator (17) had to be converted with Array.from() or spread into an array before any of these could be used — forcing the whole (possibly infinite) sequence to be realized in memory up front. ECMAScript 2025 added these methods directly onto Iterator.prototype, inherited by every generator and built-in iterator, and they are lazy: each element is only pulled through the chain as it is consumed.

.map(fn) / .filter(fn) transform / keep-matching, lazily, just like Array's
.take(n) / .drop(n) stop after n items / skip the first n items
.flatMap(fn) map to sub-iterables and flatten one level
.reduce(fn[,initial]) / .forEach(fn) consume eagerly to a single value / for side effects
.some(fn) / .every(fn) / .find(fn) consume eagerly, but stop as soon as the answer is known
.toArray() consume eagerly into a real Array
Chaining .map()/.filter()/.take() on an infinite generator is safe precisely because they are lazy -- only 3 values are ever actually produced by naturals().
function* naturals() {
  let n = 1;
  while (true) yield n++;
}

const firstThreeSquaredEvens = naturals()
  .filter(n => n % 2 === 0)
  .map(n => n * n)
  .take(3)
  .toArray();

console.log(firstThreeSquaredEvens);

[4, 16, 36]

The static Iterator.from(iterableOrIterator) wraps any iterable or bare iterator so that the result inherits these helper methods, which is useful for user-defined iterables (17.3) that do not otherwise go through Iterator.prototype.


const s = new Set([1, 2, 3, 4, 5]);

const doubledEvens = Iterator.from(s.values())
  .filter(n => n % 2 === 0)
  .map(n => n * 2)
  .toArray();

console.log(doubledEvens);

[4, 8]