npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

extra-iterator

v0.15.2

Published

An extension of the Iterator class with additional utility helper functions.

Downloads

177

Readme

extra-iterator

Static Badge Static Badge GitHub License npm bundle size

An extension of JavaScript's built-in Iterator class, with several utility functions for transforming and aggregating sequences of values.

Contributions are welcome. 🤗

Features

  • 30+ utility methods
  • Lazy operations
  • Zero dependencies 🎉
  • Fully typed with TypeScript
  • 100% test coverage

Installation

npm install extra-iterator

Runtime requirements

This package extends the built-in Iterator class and uses the Iterator Helpers API.

Use it in a runtime that already supports iterator helpers, or load an appropriate polyfill.

Usage Examples

Work with ranges

import { ExtraIterator } from 'extra-iterator';

const range = ExtraIterator.range(1, 6)
    .map(n => n * 2)
    .toArray();

console.log(range); // [1, 2, 3, 4, 5]

Manipulate the sequence

import { ExtraIterator } from 'extra-iterator';

const result = ExtraIterator.concat([1, 2, 3], [4, 5, 6])
    .dropWhile(n => n < 3)
    .take(3)
    .loop(4)
    .toArray();

console.log(result); // [3, 4, 5, 3, 4, 5, 3, 4, 5, 3, 4, 5]

Map an object's key-values pairs

import { ExtraIterator } from 'extra-iterator';

const example = {
    first: 1,
    second: 2,
    third: 3,
};

const result = ExtraIterator.from(Object.entries(example))
    .append(['fourth', 4])
    .interposeWith(([leftKey, leftValue], [rightKey, rightValue]) =>
        [`${leftKey}_${rightKey}`, (leftValue + rightValue) / 2]
    )
    .collect(Object.fromEntries);

console.log(result);
// {
//   first: 1,
//   first_second: 1.5,
//   second: 2,
//   second_third: 2.5,
//   third: 3,
//   third_fourth: 3.5,
//   fourth: 4
// }

Use ExtraIterator.from() to wrap an iterable, iterator, or array-like object

import { ExtraIterator } from 'extra-iterator';

const fromIterable = ExtraIterator.from(new Set([1, 2, 3]));
const fromGenerator = ExtraIterator.from(function*() {
    yield 'a';
    yield 'b';
}());
const fromArrayLike = ExtraIterator.from({ 0: 'x', 1: 'y', length: 2 });

console.log(fromGenerator.toArray()); // ['a', 'b']
console.log(fromArrayLike.toArray()); // ['x', 'y']

Laziness and consumption

Transformation methods are lazy. Nothing happens until you consume the iterator.

const iter = ExtraIterator.from([1, 2, 3])
    .map(value => value * 2)
    .withEach(value => console.log('seen:', value));

// No output yet.

console.log(iter.take(2).toArray());
// seen: 2
// seen: 4
// [2, 4]

Like native iterators, ExtraIterator instances are generally one-shot. Once consumed, the values are gone unless you create a new iterator.

Work with infinite sequences

import { ExtraIterator } from 'extra-iterator';

const evens = ExtraIterator.count({ start: 0, increment: 2 })
    .take(5)
    .toArray();

console.log(evens); // [0, 2, 4, 6, 8]

Flatten nested arrays

import { ExtraIterator } from 'extra-iterator';

const values = ExtraIterator.from([0, [1, [2, [3, 4]]], [5, [6]], 7])
    .flat()
    .toArray();

console.log(values); // [0, 1, 2, 3, 4, 5, 6, 7]

Group adjacent values into chunks

import { ExtraIterator } from 'extra-iterator';

const chunks = ExtraIterator.from([1, 1, 2, 3, 3, 3, 2, 2])
    .chunkWith((left, right) => left === right)
    .toArray();

console.log(chunks); // [[1, 1], [2], [3, 3, 3], [2, 2]]

Find the nearest common ancestor between all DOM paragraph elements

import { ExtraIterator } from 'extra-iterator';

const commonAncestor = ExtraIterator.from(document.querySelectorAll('p'))
    .map(element => ExtraIterator.from(function*() {
        for (let node = element.parentNode; node; node = node.parentNode) {
            yield node;
        }
    }()))
    .map(ancestorList => ancestorList.toArray().reverse())
    .zip()
    .takeWhile(nodes => new Set(nodes).size === 1)
    .last()
    .first();

API overview

See full API documentation at: leonardoraele.github.io/extra-iterator

Static constructors

  • ExtraIterator.from(source) - Iterates over any iterable object or array-like object.
  • ExtraIterator.empty() - Creates an empty iterator.
  • ExtraIterator.single(value) - Creates an iterator with a single value.
  • ExtraIterator.count() - An infinite incremental number iterator.
  • ExtraIterator.range(start, end) - Iterates over a specific range.
  • ExtraIterator.repeat(value) - An iterator that repeats a single value infinitely.
  • ExtraIterator.random() - An iterator that yields infinite random numbers.
  • ExtraIterator.randomBytes() - An iterator that yields infinite chunks of random bytes.
  • ExtraIterator.zip(...sources) - Iterates over multiple sequences simultaneously.

Standard iterator helpers that remain chainable

These native iterator-helper methods work just like the built-in methods, but return chainable ExtraIterator instances instead of built-in Iterator objects.

  • filter()
  • flatMap()
  • map()
  • take()
  • drop()

take() and drop() also support negative counts:

  • take(n) keeps the first n elements of the iterator (or the last ones if n is negative), and discard the rest.
  • drop(n) discards the first n elements (or the last ones if n is negative), and keep the rest.

Transformation helpers

  • flat() - Similar to Array.prototype.flat(), but recursive.
  • unique() - Filters repeated elements out of the iterator.
  • compact() - Filters null and undefined values out of the iterator.
  • append(value) - Appends one value to the end of the iterator.
  • prepend(value) - Prepends one value to the beginning of the iterator.
  • concat(iterable) - Concatenates multiple values to the end of the iterator.
  • prependAll(iterable) - Prepends multiple values to the beginning of the iterator.
  • takeWhile(predicate) - Similar to Iterator.prototype.take(), but with a condition instead of a fixed count.
  • dropWhile(predicate) - Similar to Iterator.prototype.drop(), but with a condition instead of a fixed count.
  • chunk(size) - Groups the elements into chunks of fixed size.
  • chunkWith(predicate) - Groups adjacent elements based on a predicate function.
  • zip(others) - Creates a new iterator that yields the values of this and the other iterators in tuples.
  • interpose(separator) - Adds a separator value between each pair of adjacent elements.
  • interposeWith(separatorProvider) - Adds a separate value between each pair of elements based on a function.
  • interleave(other) - Interleave the values of this iterator with those of another iterator.
  • splice(startIndex, deleteCount, ...newItems) - Similar to Array.prototype.splice().
  • defaultIfEmpty(provider) - If the iterator is empty, adds a default value to it.
  • loop(n = Infinity) - Expands the iterator by repeating its values n times.
  • withEach(callback) - Similar to Iterator.prototype.forEach(), but returns this iterator.

Aggregation helpers

These methods consume the iterator and return a final value instead of another iterator:

  • first() - Returns the first value or undefined if empty.
  • last() - Returns the last value or undefined if empty.
  • at(index) - Returns the value at the index, or undefined.
  • groupBy(callback) - Similar to Object.groupBy().
  • toMap(callback) - Similar to Map.groupBy().
  • toSet() - Creates a Set object with the elements of this iterator.
  • toChainOfResponsibilityFunction(invokeHandler)
  • collect(callback) - Reduce the iterator to a single value by calling a callback function.
  • sum() - Sum all numbers in the iterator.
  • count() - Returns the number of elements in the iterator.
  • testUnique() - Checks whether the iterator has duplicated elements.

You also still have the native consuming helpers provided by iterator helpers, such as reduce(), some(), every(), find(), forEach(), and toArray().

Optional [toExtra]() helper

An optional, chainable helper method that transforms any iterable object into an ExtraIterator.

import { toExtra } from 'extra-iterator/to-extra';

const result = [1, 2, 3]
    [toExtra]()    // The `[toExtra]()` method transforms the built-in array into an `ExtraIterator` object...
    .prepend(0)    // Allowing you to chain into the new  helper methods:
    .splice(2, 0, 0.5)
    .drop(-2)
    .loop(3)
    .toArray();

console.log(result);
// [0, 0.5, 1, 0, 0.5, 1, 0, 0.5, 1]

By importing the optional extra-iterator/to-extra submodule, you opt-in to expanding the global Object prototype with the [toExtra]() method as a side-effect.

This side-effect is optional. If you don't want to "polute" the global prototypes, you can still use this package as normal. Simply don't import extra-iterator/to-extra and the global prototypes will remain unchanged.

License

This project is licensed under the MIT License. See the LICENSE.txt file for the full license text.