Itertools
TypeScript port of Python's awesome itertools stdlib.
Install / Use
/learn @nvie/ItertoolsREADME
A JavaScript port of Python's awesome itertools standard library.
Usage example:
>>> import { izip, cycle } from 'itertools';
>>>
>>> const xs = [1, 2, 3, 4];
>>> const ys = ['hello', 'there'];
>>> for (const [x, y] of izip(xs, cycle(ys))) {
>>> console.log(x, y);
>>> }
1 'hello'
2 'there'
3 'hello'
4 'there'
About argument order
In Python, many of the itertools take a function as an argument. In the JS port of these we initially kept these orderings the same to stick closely to the Python functions, but in practice, it turns out to be more pragmatic to flip them, so the function gets to be the second param. Example:
In Python:
map(fn, items)
But in JavaScript:
map(items, fn)
The rationale for this flipping of argument order is because in practice, the function bodies can span multiple lines, in which case the following block will remain aesthetically pleasing:
import { map } from "itertools";
const numbers = [1, 2, 3];
const squares = map(numbers, (n) => {
//
// Do something wild with these numbers here
//
// ...
return n * n;
});
API
The itertools package consists of a few building blocks:
Ports of builtins
<a name="every" href="#every">#</a> <b>every</b>(iterable: <i>Iterable<T></i>, keyFn?: <i>Predicate<T></i>): <i>boolean</i> <>
Returns true when every of the items in iterable are truthy. An optional key function can be used to define what truthiness means for this specific collection.
Examples:
every([]); // => true
every([0]); // => false
every([0, 1, 2]); // => false
every([1, 2, 3]); // => true
Examples with using a key function:
every([2, 4, 6], (n) => n % 2 === 0); // => true
every([2, 4, 5], (n) => n % 2 === 0); // => false
<a name="some" href="#some">#</a> <b>some</b>(iterable: <i>Iterable<T></i>, keyFn?: <i>Predicate<T></i>): <i>boolean</i> <>
Returns true when some of the items in iterable are truthy. An optional key function can be used to define what truthiness means for this specific collection.
Examples:
some([]); // => false
some([0]); // => false
some([0, 1, null, undefined]); // => true
Examples with using a key function:
some([1, 4, 5], (n) => n % 2 === 0); // => true
some([{ name: "Bob" }, { name: "Alice" }], (person) => person.name.startsWith("C")); // => false
<a name="contains" href="#contains">#</a> <b>contains</b>(haystack: <i>Iterable<T></i>, needle: <i>T</i>): <i>boolean</i> <>
Returns true when some of the items in the iterable are equal to the target object.
Examples:
contains([], "whatever"); // => false
contains([3], 42); // => false
contains([3], 3); // => true
contains([0, 1, 2], 2); // => true
<a name="enumerate" href="#enumerate">#</a> <b>enumerate</b>(iterable: <i>Iterable<T></i>, start: <i>number = 0</i>): <i>Iterable<[number, T]></i> <>
Returns an iterable of enumeration pairs. Iterable must be a sequence, an iterator, or some other object which supports iteration. The elements produced by returns a tuple containing a counter value (starting from 0 by default) and the values obtained from iterating over given iterable.
Example:
import { enumerate } from "itertools";
console.log([...enumerate(["hello", "world"])]);
// [0, 'hello'], [1, 'world']]
<a name="filter" href="#filter">#</a> <b>filter</b>(iterable: <i>Iterable<T></i>, predicate: <i>Predicate<T></i>): <i>T[]</i> <>
Eager version of ifilter.
<a name="iter" href="#iter">#</a> <b>iter</b>(iterable: <i>Iterable<T></i>): <i>Iterator<T></i> <>
Returns an iterator object for the given iterable. This can be used to manually get an iterator for any iterable datastructure. The purpose and main use case of this function is to get a single iterator (a thing with state, think of it as a "cursor") which can only be consumed once.
<a name="map" href="#map">#</a> <b>map</b>(iterable: Iterable<T>, mapper: (item: T) => V): V[] <>
Eager version of imap.
<a name="max" href="#max">#</a> <b>max</b>(iterable: <i>Iterable<T></i>, keyFn?: <i>(item: T) => number</i>): <i>T | undefined</i> <>
Return the largest item in an iterable. Only works for numbers, as ordering is
pretty poorly defined on any other data type in JS. The optional keyFn
argument specifies a one-argument ordering function like that used for
sorted.
If the iterable is empty, undefined is returned.
If multiple items are maximal, the function returns either one of them, but which one is not defined.
<a name="min" href="#min">#</a> <b>min</b>(iterable: <i>Iterable<T></i>, keyFn?: <i>(item: T) => number</i>): <i>T | undefined</i> <>
Return the smallest item in an iterable. Only works for numbers, as ordering
is pretty poorly defined on any other data type in JS. The optional keyFn
argument specifies a one-argument ordering function like that used for
sorted.
If the iterable is empty, undefined is returned.
If multiple items are minimal, the function returns either one of them, but which one is not defined.
<a name="range" href="#range">#</a> <b>range</b>(stop: <i>number</i>): <i>Iterable<number></i> <><br /> <a name="range" href="#range">#</a> <b>range</b>(start: <i>number</i>, stop: <i>number</i>, step: <i>number</i> = 1): <i>Iterable<number></i> <>
Returns an iterator producing all the numbers in the given range one by one,
starting from start (default 0), as long as i < stop, in increments of
step (default 1).
range(a) is a convenient shorthand for range(0, a).
Various valid invocations:
range(5) // 0, 1, 2, 3, 4
range(0, 5) // 0, 1, 2, 3, 4
range(0, 5, 2) // 0, 2, 4
range(5, 0, -1) // 5, 4, 3, 2, 1
range(5, 0) // (empty)
range(-3) // (empty)
For a positive step, the iterator will keep producing values n as long as
the stop condition n < stop is satisfied.
For a negative step, the iterator will keep producing values n as long as
the stop condition n > stop is satisfied.
The produced range will be empty if the first value to produce already does not meet the value constraint.
<a name="xrange" href="#xrange">#</a> <b>xrange</b>(stop: <i>number</i>): <i>number[]</i> <><br /> <a name="xrange" href="#xrange">#</a> <b>xrange</b>(start: <i>number</i>, stop: <i>number</i>, step: <i>number</i> = 1): <i>number[]</i> <>
Returns an array with all the numbers in the given range, starting from
start (default 0), as long as i < stop, in increments of step
(default 1).
xrange(5) is a convenient shorthand for Array.from(range(5)).
Various valid invocations:
xrange(5) // [0, 1, 2, 3, 4]
xrange(2, 5) // [2, 3, 4]
xrange(0, 5, 2) // [0, 2, 4]
xrange(5, 0, -1) // [5, 4, 3, 2, 1]
xrange(5, 0) // []
For a positive step, the iterator will keep producing values n as long as
the stop condition n < stop is satisfied.
For a negative step, the iterator will keep producing values n as long as
the stop condition n > stop is satisfied.
The produced range will be empty if the first value to produce already does not meet the value constraint.
Don't use this on large or infinite ranges, as it will allocate a large array in memory.
<a name="reduce" href="#reduce">#</a> <b>reduce</b>(iterable: <i>Iterable<T></i>, reducer: <i>(O, T, number) => O</i>, start: <i>O</i>): <i>O</i> <><br /> <a name="reduce" href="#reduce">#</a> <b>reduce</b>(iterable: <i>Iterable<T></i>, reducer: <i>(T, T, number) => T</i>): <i>T | undefined</i> <>
Apply function of two arguments cumulatively to the items of sequence, from left to right, so as to reduce the sequence to a single value. For e
