itt
Iteration tools.
{ const seen = return itt } /*2 is prime!3 is prime!5 is prime!7 is prime!11 is prime!...983 is prime!991 is prime!997 is prime!*/ fs /*44 49 52 43 00 00 00 02 00 00 00 0c 5d 89 05 55 DIRC········]··U0f ae b1 b8 5c 7d 45 63 00 00 00 00 00 00 00 00 ····\}Ec········00 00 00 00 00 00 81 a4 00 00 00 00 00 00 00 00 ················00 00 00 37 f5 f6 f6 c8 60 d9 4b 6a 42 3c 5a d1 ···7····`·KjB<Z·f5 29 a0 f3 eb db 46 46 00 0a 2e 67 69 74 69 67 ·)····FF··.gitig6e 6f 72 65 00 00 00 00 00 00 00 00 5d 89 05 55 nore········]··U17 3b 61 b0 5c 79 af 4f 00 00 00 00 00 00 00 00 ·;a·\y·O········00 00 00 00 00 00 81 a4 00 00 00 00 00 00 00 00 ················*/
Install
$ npm i itt
Use
const itt =
API
Constructors — from(…) empty() range(…) irange(…) replicate(…) forever(…) iterate(…) split(…) exec(…)
Object iterators — entries(…) keys(…) values(…)
Utilities — is(…) generator(…)
Iterator Methods
Slicing — .slice .drop .dropWhile .dropLast .take .takeWhile .takeLast .tail .init
Transforming — .map .flatMap .filter .reject .partition .scan .scan1
Querying — .first .last .pick .count .every .some .tap
Searching — .detect .find .findLast .findIndex .findLastIndex .indexOf .lastIndexOf .includes
Combinatorics — .cartesianProduct .permutations .combinations
Manipulating — .enumerate .intersperse .cycle .repeat .unique .flatten .chunksOf .chunksBy .subsequences .lookahead .transpose
Combining — .concat .zip .parallel .push .unshift
Reducing — .reduce .reduce1 .inject .sum .mean .product .max .min .minMax .join .groupBy .keyBy .forEach .drain
Conversion — .toArray .toSet .toMap .toObject
Forking — .fork
Constructors
itt(thing), itt.from(thing)
Wraps an iterator. The wrapper is also iterable, and supports the methods listed below. All functions and methods which return iterators automatically wrap them.
/* [ 'BAR', 'BAZ' ] */
Note: Many of the examples use .toArray()
to show the elements of an iterator, but of course a feature of iterators is that they don't compute elements ahead of time (or even at all, depending on how they are iterated). For example, consider the following:
const squares = ittfor const y of squares console/* compute 0log 0compute 1log 1compute 2log 4*/
empty()
An iterator which yields no values.
itt/* [] */
range([start = 0,] end, [skip = 1])
An iterator over an integer range from start
(inclusive) to end
(exclusive), incrementing or decrementing by skip
.
itt/* [ 0, 1, 4, 9, 16 ] */
irange([start = 0, [skip = 1]])
An iterator over the integers starting at start
and incrementing or decrementing by skip
. Best paired with .take
or its variants.
itt/* [ 0, 1, 4, 9, 16 ] */
replicate(n, x)
An iterator which yields x
n
times.
itt/* [ 0, 0, 0, 0, 0 ] */
forever(x)
An iterator which yields x
forever.
itt/* [ 0, 0, 0, 0, 0 ] */
iterate(x, fn)
An iterator which yields x
, fn(x)
, fn(fn(x))
, etc.
itt/* [ 1, 2, 4, 8, 16 ] */
split(string, [sep = undefined, [limit = Infinity]])
An iterator which yields slices of string
, delimited by sep
, up to a maximum of limit
items. Just like the built-in String.prototype.split
, but does not create an intermediate array.
itt/* ['one', 'two', 'three', 'four', 'five'] */itt/* ['one', 'c', 'two', 'b', 'three', 'c', 'four'] */
exec(pattern, string)
An iterator which yields all matches of pattern
in string
.
itt/* 3.75 */
Object iterators
entries(o)
An iterator over the keys and values of an object.
itt/* [ [ 'a', 1 ], [ 'b', 2 ] ] */ itt/* { a: 1, b: 4, c: 9 } */
keys(o)
An iterator over the keys of an object.
itt/* [ 'A', 'B', 'C' ] */
values(o)
An iterator over the values of an object.
itt/* [ 1, 4, 9 ] */
Utilities
itt.is(thing)
True if thing
is iterable or an iterator.
itt // falseitt // trueitt // trueitt // true
itt.generator(g)
Takes a generator function and returns a generator function which returns wrapped iterators.
const fn = itt/* [ 1, 4, 9, 4, 1 ] */
Iterator Methods
Methods can also be used statically by passing an iterator as the last argument. For example:
itt /* '1,3,5,7,9' */itt /* '1,3,5,7,9' */
Slicing
.slice([start = 0, [end = undefined]])
Like Array.prototype.slice
. Returns an iterator which yields a subsequence of the elements of this iterator, starting at the start
th element (inclusive) and ending at the end
th element (exclusive).
If an index is negative, that index is treated as an index from the end of the iterator. If end
is missing, it is treated as if it were the number of elements in this iterator.
itt/* [ 1, 4, 9 ] */ itt/* [ 1, 4, 9, 16, 25, 36, 49, 64 ] */ itt/* [ 49, 64, 81 ] */
.drop([n = 1])
An iterator which yields all but the first n
elements of this iterator.
itt/* [ 3, 4, 5, 6, 7, 8, 9 ] */
.dropWhile([fn = undefined])
An iterator which skips elements of this iterator until fn(x)
returns a falsy value for an element x
, then yields x
and every element after it. If fn
is undefined, skips until x
is falsy.
/* [ 16, 25, 16, 9, 4, 1 ] */
.dropLast([n = 1])
An iterator which yields all but the last n
elements of this iterator.
itt/* [ 0, 1, 2, 3, 4, 5, 6 ] */
Note: This method caches at most n
elements of this iterator. It does not pull elements from this iterator, however, until its return value is iterated.
.take([n = 1])
An iterator which yields the first n
elements of this iterator.
itt/* [ 0, 1, 2, 3 ] */
.takeWhile([fn = undefined])
An iterator which yields elements of this iterator until fn(x)
returns a falsy value for an element x
, then stops without yielding x
. If fn
is undefined, yields until x
is falsy.
/* [ 1, 4, 9 ] */
.takeLast([n = 1])
An iterator which yields the last n
elements of this iterator. If this iterator yields fewer than n
elements, it yields all available elements.
itt/* [ 7, 8, 9 ] */
Note: This method caches at most n
elements of this iterator. It does not pull elements from this iterator, however, until its return value is iterated.
.tail()
An iterator which yields all but the first element of this iterator.
itt/* [ 1, 4, 9, 16, 25, 36, 49, 64, 81 ] */
.init()
An iterator which yields all but the last element of this iterator.
itt/* [ 0, 1, 4, 9, 16, 25, 36, 49, 64 ] */
Transforming
.map(fn)
An iterator which yields fn(x)
for each element x
of this iterator.
itt/* [ 0, 1, 4, 9, 16 ] */
.flatMap(fn)
An iterator which yields the elements of fn(x)
for each element x
of this iterator. Equivalent to .map(fn).flatten()
.
itt/* [ 0, 0, 1, 1, 2, 4, 3, 9, 4, 16 ] */
.filter([fn = undefined])
An iterator which yields the elements of this iterator for which fn
returns a truthy value (if fn
is undefined, the truthy elements of this iterator).
/* [ 1, 5, 3, 5, 9, 95, 1, 5 ] */
.reject([fn = undefined])
An iterator which yields the elements of this iterator for which fn
returns a falsy value (if fn
is undefined, the falsy elements of this iterator).
/* [ 2, 4, 4, 2, 8 ] */
.partition([fn = undefined])
A pair of iterators. The first yields the elements of this iterator for which fn
returns a truthy value, and the second yields the elements for which it returns a falsy value; if fn
is undefined, the first yields truthy elements and the second yields falsy elements.
const a b = a // [ 1, 5, 3, 5, 9, 95, 1, 5 ]b // [ 2, 4, 4, 2 ]
.scan(a, fn)
Accumulates a = fn(a, x)
for each element of this iterator, in iteration order, and yields each intermediate result. The resultant iterator always yields the same number of elements as this iterator.
itt/* [ 0, 1, 3, 6, 10 ] */
.scan1(fn)
Like .scan
, but draws (and yields) the initial value of a
from the first element of this iterator, accumulating a = fn(a, x)
for each subsequent element. The resultant iterator always yields the same number of elements as this iterator.
itt/* [ 0, 1, 3, 6, 10 ] */
Querying
.first()
.head() [alias]
The first element of this iterator, or undefined
if this iterator is empty.
itt/* 25 */
.last()
The last element of this iterator, or undefined
if this iterator is empty.
itt/* 81 */
.pick(i)
The i
th element of this iterator, or undefined
if it does not exist.
itt/* 9 */
.count()
The number of elements in this iterator.
itt/* 5 */
.every([fn = undefined])
True if fn(x)
returns a truthy value for every element x
of this iterator. If fn
is undefined, true if every element is truthy.
/* false */ itt/* true */
.some([fn = undefined])
True if fn(x)
returns a truthy value for any element x
of this iterator. If fn
is undefined, true if any element is truthy.
/* true */ itt/* false */
.tap(fn)
An iterator which yields each element x
of this iterator after calling fn(x)
. Useful for inspecting intermediate iterators with console.log
and for running iterators through side-effectful functions.
const alnum = itt console/*012...xyztotal: 63*/
Searching
.detect(fn)
Applies fn
to each element and returns the first truthy result, or undefined
if none exists. Equivalent to .map(fn).find()
. If fn
is undefined, returns the first truthy element, like .find()
.
/* [ 'rr' ] */ const people = name: 'Olivia' name: 'Emily' favoriteBook: 'The Grapes of Wrath' name: 'Jessica' favoriteBook: 'The Sun Also Rises'/* 'The Grapes of Wrath' *//* undefined */
.find([fn = undefined])
The first element of this iterator for which fn
returns a truthy value (if fn
is undefined, the first truthy element of this iterator), or undefined
if none exists.
itt/* 16 */ itt/* undefined */
.findLast([fn = undefined])
The last element of this iterator for which fn
returns a truthy value (if fn
is undefined, the last truthy element of this iterator), or undefined
if none exists.
itt/* 81 */ itt/* undefined */
.findIndex([fn = undefined])
The 0-based index of the first element of this iterator for which fn
returns a truthy value (if fn
is undefined, the first truthy element of this iterator), or -1 if none exists.
itt/* 4 */ itt/* -1 */
.findLastIndex([fn = undefined])
The 0-based index of the last element of this iterator for which fn
returns a truthy value (if fn
is undefined, the last truthy element of this iterator), or -1 if none exists.
itt/* 9 */ itt/* -1 */
.indexOf(x)
The 0-based index of the first element of this iterator which is strictly equal (===
) to x
, or -1 if none exists.
/* 1 */
.lastIndexOf(x)
The 0-based index of the last element of this iterator which is strictly equal (===
) to x
, or -1 if none exists.
/* 3 */
.includes(x)
True if any element of this iterator is strictly equal (===
) to x
.
itt/* true */ itt/* false */
Combinatorics
.cartesianProduct(xs, [...])
An iterator of elements in the Cartesian product of the arguments.
/* [ 'AD', 'AE', 'AF', 'BD', 'BE', 'BF', 'CD', 'CE', 'CF' ] */
Note: This method can be called statically with any number of arguments, and yields arrays in argument order.
itt /* [ 'ACE', 'ACF', 'ADE', 'ADF', 'BCE', 'BCF', 'BDE', 'BDF' ] */
.cartesianProduct([n = 1])
An iterator of elements in the Cartesian product this
n
, i.e., the Cartesian product of n
copies of this iterator.
/* [ '000', '001', '010', '011', '100', '101', '110', '111' ] */
.permutations([n = undefined])
An iterator of all permutations of elements of this iterator of length n
, or of the same length as this iterator if n
is undefined.
/* [ 'ABC', 'ACB', 'BCA', 'BAC', 'CAB', 'CBA' ] */ /* [ 'AB', 'AC', 'BC', 'BA', 'CA', 'CB' ] */
.combinations([n = undefined])
An iterator of all combinations of elements of this iterator of length n
in iteration order, or of the same length as this iterator if n
is undefined.
/* [ 'ABC', 'ABD', 'ABE', 'ACD', 'ACE', 'ADE', 'BCD', 'BCE', 'BDE', 'CDE' ] */
Manipulating
.enumerate()
An iterator which yields pairs, each containing a 0-based index and element of this iterator.
/* [ [ 0, 'foo' ], [ 1, 'bar' ], [ 2, 'baz' ] ] */
.intersperse(sep)
An iterator which yields sep
between each element of this iterator.
/* [ 'foo', 'or', 'bar', 'or', 'baz' ] */
.cycle()
An iterator which yields the elements of this iterator, in order, cycled forever.
itt/* [ 0, 1, 2, 0, 1, 2, 0, 1, 2, 0 ] */
Note: This method caches all elements of this iterator. It does not pull elements from this iterator, however, until its return value is iterated.
.repeat(n)
An iterator which yields the elements of this iterator, in order, cycled n
times.
itt/* [ 0, 1, 2, 0, 1, 2, 0, 1, 2 ] */
Note: This method caches all elements of this iterator. It does not pull elements from this iterator, however, until its return value is iterated.
.unique()
An iterator which yields elements of this iterator and skips elements which are Set
-membership-equal to any that have already appeared.
/* [ 1, 4, 7, 6, 5, 2, 0, 9 ] */
Note: This method caches all elements of this iterator. It does not pull elements from this iterator, however, until its return value is iterated.
.flatten()
An iterator which yields the elements of each element of this iterator. Each element must itself be iterable.
/* [ 1, 2, 3, 4, 5, 6 ] */
.chunksOf(n = 2)
An iterator which yields arrays of n
elements from this iterator, in sequence, without duplication. If there are not an even multiple of n
elements in total, the last array is shorter.
itt/* [ [ 0, 1, 2 ], [ 3, 4, 5 ], [ 6, 7, 8 ], [ 9 ] ] */
.chunksBy(fn)
An iterator which yields arrays of elements from this iterator, in sequence, without duplication. Each array is extended with the next element from this iterator until fn(newEl, prevEl, currentArray)
returns false.
const sameParity = x % 2 === y % 2/* [ [ 1, 3, 5, 7 ], [ 2, 4, 6 ], [ 9, 13 ] ] */ itt/* [ [ 0, 1, 2 ], [ 3, 4, 5 ], [ 6, 7, 8 ], [ 9 ] ] */
.subsequences(n = 2)
An iterator which yields each subsequence of n
elements in this iterator. If there are fewer than n
elements, yields nothing.
itt/* [ [ 0, 1, 2 ], [ 1, 2, 3 ], [ 2, 3, 4 ] ] */itt/* [] */
Note: This method caches at most n
elements of this iterator. It does not pull elements from this iterator, however, until its return value is iterated.
.lookahead(n = 1)
An iterator which yields arrays, each containing an element from this iterator and n
elements of lookahead (or undefined
if past the end of this iterator).
for const here next of itt console/*0 11 22 33 44 undefined*/
Note: This method caches at most n
elements of this iterator. It does not pull elements from this iterator, however, until its return value is iterated.
.transpose()
An iterator which yields arrays of elements at sequential indices in each element of this iterator, whose elements must be iterable. Equivalent to zip(...this)
.
/* [ [ 1, 4, 7 ], [ 2, 5, 8 ], [ 3, 6, 9 ] ] */
Combining
.concat(xs, [...])
An iterator which yields the elements of this iterator, followed by the elements of xs
, etc.
itt/* [ 0, 1, 2, 0, 1, 2, 3, 4, 0, 1, 2 ] */
Note: This method can be called statically with any number of arguments, and yields elements in argument order.
itt/* [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ] */
.zip(xs, [...])
An iterator which yields arrays containing one element from this iterator and one element from each argument iterator, stopping when any iterator is done.
itt/* [ [ 0, 'a' ], [ 1, 'b' ], [ 2, 'c' ] ] */
Note: This method can be called statically with any number of arguments, and yields arrays in argument order.
itt/* [ [ 1, 4, 7 ], [ 2, 5, 8 ], [ 3, 6, 9 ] ] */
.parallel(xs, [...])
An iterator which yields arrays containing one element from this iterator and one element from each argument iterator, stopping when all iterators are done.
itt/* [ [ 0, 'a' ], [ 1, 'b' ], [ 2, 'c' ], [ 3, undefined ], [ 4, undefined ] ] */
Note: This method can be called statically with any number of arguments, and yields arrays in argument order.
itt/* [ [ 1, 4, 7 ], [ 2, 5, 8 ], [ 3, 6, 9 ] ] */
.push(x, [...])
An iterator which yields the elements of this iterator, followed by x
, etc.
/* [ 'foo', 'bar', 'baz', 'qux' ] */
.unshift(x, [...])
An iterator which yields x
, etc., followed by the elements of this iterator.
/* [ 'foo', 'bar', 'baz', 'qux' ] */
Reducing
.reduce(a, fn)
Accumulates a = fn(a, x)
for each element of this iterator, in iteration order, then returns a
.
itt/* 15 */
.reduce1(fn)
Like .reduce
, but draws the initial value of a
from the first element of this iterator, accumulating a = fn(a, x)
for each subsequent element and then returning a
. Returns undefined
if this iterator is empty.
itt/* 15 */
.inject(a, fn)
Calls fn(a, x)
for each element of this iterator, in iteration order, then returns a
.
/* { foo: true, bar: true, baz: true } */
.sum()
The sum of the elements of this iterator.
itt/* 15 */
.mean()
The arithmetic mean of the elements of this iterator. Returns NaN
if this iterator has no elements.
itt/* 2.5 */
.product()
The product of the elements of this iterator.
ittproduct/* 120 */
.max()
The maximum element of this iterator.
/* 81 */
.min()
The minimum element of this iterator.
/* 1 */
.minMax()
The minimum and maximum elements of this iterator as a pair [min, max]
.
/* [1, 81] */
.join(sep = ',')
Stringifies and concatenates all values, separated by sep
, like Array.prototype.join
.
itt /* '0,1,2,3,4' */
.groupBy(fn, [unique = false])
Calls fn(x)
for each element of this iterator and returns a map from return values of fn
to arrays of elements. If unique
is true, use sets instead of arrays. (If fn
is a pure function, this is equivalent to .unique().groupBy(fn)
)
itt/* Map { 0 => [ 0, 3, 6, 9 ], 1 => [ 1, 4, 7 ], 2 => [ 2, 5, 8 ] } */ /* Map { 1 => Set { 1, 4, 7 }, 0 => Set { 6, 0, 9 }, 2 => Set { 5, 2 } } */
.keyBy(fn)
Calls fn(x)
for each element of this iterator and returns a map from return values of fn
to elements. Later elements overwrite earlier elements in the map.
/* Map { 'jane' => { name: 'Jane', age: 24 }, 'alice' => { name: 'Alice', age: 53 }, 'kyle' => { name: 'Kyle', age: 33 } } */
.forEach(fn)
Calls fn(x)
for each element of this iterator, in iteration order. Ergonomically nicer than a for (…) {…}
loop after a sequence of method calls or when not passing a function literal as an argument. Equivalent to .tap(fn).drain()
.
itt /*19254981*/
.drain()
Consumes all elements of this iterator and returns nothing (undefined
). Useful for iterators with side effects. Equivalent to .forEach(() => {})
.
itt/*01234*/
Conversion
.toArray()
An array of the elements in this iterator. Equivalent to Array.from(this)
.
itt/* [ 0, 1, 2, 3, 4 ] */
.toSet()
A Set of the elements in this iterator. Equivalent to new Set(this)
.
itt/* Set { 0, 1, 2, 3, 4 } */
.toMap()
A Map of the key-value pairs in this iterator. Equivalent to new Map(this)
.
const m = mmm/* Map { 'a!' => 1, 'b!' => 4, 'c!' => 9 } */
.toObject(empty = false)
An object containing the key-value pairs in this iterator. If empty
is true, starts with Object.create(null)
instead of {}
.
/* { foo: 'FOO', bar: 'BAR', baz: 'BAZ' } */
Forking
.fork(n = 2)
An array of n
iterators which all yield every element of this iterator in sequence.
const a b = ittitt/* [ [ 0, 0 ], [ 1, 1 ], [ 4, 8 ], [ 9, 27 ], [ 16, 64 ] ] */
Note: This method caches some elements of this iterator. As any derived iterator advances, new elements are cached, and once every derived iterator has advanced past an element, that element is discarded.