Package Exports
- itertools-ts
- itertools-ts/src/index.ts
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (itertools-ts) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
IterTools implementation for TypeScript
Inspired by Python — designed for TypeScript.
Features
IterTools makes you an iteration superstar by providing two types of tools:
- Loop iteration tools
- Stream iteration tools
Loop Iteration Tools Example
import { multi } from 'itertools-ts';
for (const [letter, number] of multi.zip(['a', 'b'], [1, 2])) {
console.log(`${letter}${number}`); // a1, b2
}Stream Iteration Tools Example
import { Stream } from 'itertools-ts';
const result = Stream.of([1, 1, 2, 2, 3, 4, 5])
.distinct() // [1, 2, 3, 4, 5]
.map((x) => $x**2) // [1, 4, 9, 16, 25]
.filter((x) => x < 10) // [1, 4, 9]
.toValue((carry, datum) => carry + datum, 0); // 14All functions work on iterable collections:
ArraySetMapStringGeneratorIterableIterator
Setup
npm i itertools-tsQuick Reference
Loop Iteration Tools
Multi Iteration
| Iterator | Description | Code Snippet |
|---|---|---|
chain |
Chain multiple iterables together | multi.chain(list1, list2) |
zip |
Iterate multiple collections simultaneously until the shortest iterator completes | multi.zip(list1, list2) |
zipEqual |
Iterate multiple collections of equal length simultaneously, error if lengths not equal | multi.zipEqual(list1, list2) |
zipLongest |
Iterate multiple collections simultaneously until the longest iterator completes | multi.zipLongest(list1, list2) |
Single Iteration
| Iterator | Description | Code Snippet |
|---|---|---|
chunkwise |
Iterate by chunks | single.chunkwise(data, chunkSize) |
chunkwiseOverlap |
Iterate by overlapped chunks | single.chunkwiseOverlap(data, chunkSize, overlapSize) |
filter |
Filter for elements where predicate is true | single.filter(data, predicate) |
flatMap |
Map function onto items and flatten result | single.flatMap(data, mapper) |
flatten |
Flatten multidimensional iterable | single.flatten(data, [dimensions]) |
limit |
Iterate up to a limit | single.limit(data, limit) |
map |
Map function onto each item | single.map(data, mapper) |
pairwise |
Iterate successive overlapping pairs | single.pairwise(data) |
repeat |
Repeat an item a number of times | single.repeat(item, repetitions) |
Reduce
| Reducer | Description | Code Snippet |
|---|---|---|
toValue |
Reduce to value using callable reducer | reduce.toValue(data, reducer, initialValue) |
Set and multiset Iteration
| Iterator | Description | Code Snippet |
|---|---|---|
distinct |
Iterate only distinct items | set.distinct(data) |
Summary
| Summary | Description | Code Snippet |
|---|---|---|
isIterable |
True if given data is iterable | summary.isIterable(data) |
isIterator |
True if given data is iterator | summary.isIterator(data) |
Transform
| Iterator | Description | Code Snippet |
|---|---|---|
toArray |
Transforms collection to array | transform.toArray(data) |
toIterable |
Transforms collection to iterable | transform.toIterable(data) |
toIterator |
Transforms collection to iterator | transform.toIterator(data) |
Stream Iteration Tools
Stream Sources
| Source | Description | Code Snippet |
|---|---|---|
of |
Create a stream from an iterable | Stream.of(iterable) |
ofEmpty |
Create an empty stream | Stream.ofEmpty() |
Stream Operations
| Operation | Description | Code Snippet |
|---|---|---|
chainWith |
Chain iterable source withs given iterables together into a single iteration | stream.chainWith(...iterables) |
chunkwise |
Iterate by chunks | stream.chunkwise(chunkSize) |
chunkwiseOverlap |
Iterate by overlapped chunks | stream.chunkwiseOverlap(chunkSize, overlap) |
distinct |
Filter out elements: iterate only unique items | stream.distinct() |
filter |
Filter for only elements where the predicate function is true | stream.filter(predicate) |
flatMap |
Map function onto elements and flatten result | stream.flatMap(mapper) |
flatten |
Flatten multidimensional stream | stream.flatten([dimensions]) |
limit |
Limit the stream's iteration | stream.limit(limit) |
map |
Map function onto elements | stream.map(mapper) |
pairwise |
Return pairs of elements from iterable source | stream.pairwise() |
zipWith |
Iterate iterable source with another iterable collections simultaneously | stream.zipWith(...iterables) |
zipLongestWith |
Iterate iterable source with another iterable collections simultaneously | stream.zipLongestWith(...iterables) |
zipEqualWith |
Iterate iterable source with another iterable collections of equal lengths simultaneously | stream.zipEqualWith(...iterables) |
Stream Terminal Operations
Transformation Terminal Operations
| Terminal Operation | Description | Code Snippet |
|---|---|---|
toArray |
Returns array of stream elements | stream.toArray() |
Reduction Terminal Operations
| Terminal Operation | Description | Code Snippet |
|---|---|---|
toValue |
Reduces stream like array.reduce() function | stream.toValue(reducer, initialValue) |
Usage
Multi Iteration
Chain
Chain multiple iterables together into a single continuous sequence.
function *chain(
...iterables: Array<Iterable<unknown>|Iterator<unknown>>
): Iterable<unknown>import { multi } from 'itertools-ts';
const prequels = ['Phantom Menace', 'Attack of the Clones', 'Revenge of the Sith'];
const originals = ['A New Hope', 'Empire Strikes Back', 'Return of the Jedi'];
for (const movie of multi.chain(prequels, originals)) {
console.log(movie);
}
// 'Phantom Menace', 'Attack of the Clones', 'Revenge of the Sith', 'A New Hope', 'Empire Strikes Back', 'Return of the Jedi'Zip
Iterate multiple iterable collections simultaneously.
function *zip(
...iterables: Array<Iterable<unknown>|Iterator<unknown>>
): Iterable<Array<unknown>>import { multi } from 'itertools-ts';
const languages = ['PHP', 'Python', 'Java', 'Go'];
const mascots = ['elephant', 'snake', 'bean', 'gopher'];
for (const [language, mascot] of multi.zip(languages, mascots)) {
console.log(`The ${language} language mascot is an ${mascot}.`);
}
// The PHP language mascot is an elephant.
// ...Zip works with multiple iterable inputs - not limited to just two.
import { multi } from 'itertools-ts';
const names = ['Ryu', 'Ken', 'Chun Li', 'Guile'];
const countries = ['Japan', 'USA', 'China', 'USA'];
const signatureMoves = ['hadouken', 'shoryuken', 'spinning bird kick', 'sonic boom'];
for (const [name, country, signatureMove] of multi.zip(names, countries, signatureMoves)) {
const streetFighter = new StreetFighter(name, country, signatureMove);
}Note: For uneven lengths, iteration stops when the shortest iterable is exhausted.
Zip Longest
Iterate multiple iterable collections simultaneously.
function *zipLongest(
...iterables: Array<Iterable<unknown>|Iterator<unknown>>
): Iterable<Array<unknown>>For uneven lengths, the exhausted iterables will produce undefined for the remaining iterations.
import { multi } from 'itertools-ts';
const letters = ['A', 'B', 'C'];
const numbers = [1, 2];
for (const [letter, number] of multi.zipLongest(letters, numbers)) {
// ['A', 1], ['B', 2], ['C', undefined]
}Zip Equal
Iterate multiple iterable collections with equal lengths simultaneously.
Throws LengthException if lengths are not equal, meaning that at least one iterator ends before the others.
function *zipEqual(
...iterables: Array<Iterable<unknown>|Iterator<unknown>>
): Iterable<Array<unknown>>import { multi } from 'itertools-ts';
const letters = ['A', 'B', 'C'];
const numbers = [1, 2, 3];
for (const [letter, number] of multi.zipEqual(letters, numbers)) {
// ['A', 1], ['B', 2], ['C', 3]
}Single Iteration
Chunkwise
Return elements in chunks of a certain size.
function *chunkwise<T>(
data: Iterable<T>|Iterator<T>,
chunkSize: number,
): Iterable<Array<T>>Chunk size must be at least 1.
import { single } from 'itertools-ts';
const movies = [
'Phantom Menace', 'Attack of the Clones', 'Revenge of the Sith',
'A New Hope', 'Empire Strikes Back', 'Return of the Jedi',
'The Force Awakens', 'The Last Jedi', 'The Rise of Skywalker',
];
const trilogies = [];
for (const trilogy of single.chunkwise(movies, 3)) {
trilogies.push(trilogy);
}
// [
// ['Phantom Menace', 'Attack of the Clones', 'Revenge of the Sith'],
// ['A New Hope', 'Empire Strikes Back', 'Return of the Jedi'],
// ['The Force Awakens', 'The Last Jedi', 'The Rise of Skywalker]',
// ]Chunkwise Overlap
Return overlapped chunks of elements.
function *chunkwiseOverlap<T>(
data: Iterable<T>|Iterator<T>,
chunkSize: number,
overlapSize: number,
includeIncompleteTail: boolean = true,
): Iterable<Array<T>>- Chunk size must be at least 1.
- Overlap size must be less than chunk size.
import { single } from 'itertools-ts';
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
for (const chunk of single.chunkwiseOverlap(numbers, 3, 1)) {
// [1, 2, 3], [3, 4, 5], [5, 6, 7], [7, 8, 9], [9, 10]
}Filter
Filter out elements from the iterable only returning elements where the predicate function is true.
function *filter<T>(
data: Iterable<T>|Iterator<T>,
predicate: (datum: T) => boolean,
): Iterable<T>import { single } from 'itertools-ts';
const starWarsEpisodes = [1, 2, 3, 4, 5, 6, 7, 8, 9];
const goodMoviePredicate = (episode) => episode > 3 && episode < 8;
for (const goodMovie of single.filter(starWarsEpisodes, goodMoviePredicate)) {
console.log(goodMovie);
}
// 4, 5, 6, 7Flat Map
Map a function only the elements of the iterable and then flatten the results.
function *flatMap<TInput, TOutput>(
data: Iterable<TInput>|Iterator<TInput>,
mapper: FlatMapper<TInput, TOutput>,
): Iterable<TOutput>import { single } from 'itertools-ts';
const data = [1, 2, 3, 4, 5];
const mapper = (item) => [item, -item];
for (number of single.flatMap(data, mapper)) {
console.log(number);
}
// 1 -1 2 -2 3 -3 4 -4 5 -5Flatten
Flatten a multidimensional iterable.
function *flatten(
data: Iterable<unknown>|Iterator<unknown>,
dimensions: number = Infinity,
): Iterable<unknown>import { single } from 'itertools-ts';
const multidimensional = [1, [2, 3], [4, 5]];
const flattened = [];
for (const number of single.flatten(multidimensional)) {
flattened.push(number);
}
// [1, 2, 3, 4, 5]Limit
Iterate up to a limit.
Stops even if more data available if limit reached.
function *limit<T>(data: Iterable<T>|Iterator<T>, count: number): Iterable<T>import { single } from 'itertools-ts';
const matrixMovies = ['The Matrix', 'The Matrix Reloaded', 'The Matrix Revolutions', 'The Matrix Resurrections'];
const limit = 1;
for (const goodMovie of single.limit(matrixMovies, limit)) {
console.log(goodMovie);
}
// 'The Matrix' (and nothing else)Map
Map a function onto each element.
function *map<TInput, TOutput>(
data: Iterable<TInput>|Iterator<TInput>,
mapper: (datum: TInput) => TOutput,
): Iterable<TOutput>import { single } from 'itertools-ts';
const grades = [100, 99, 95, 98, 100];
const strictParentsOpinion = (g) => (g === 100) ? 'A' : 'F';
for (const actualGrade of single.map(grades, strictParentsOpinion)) {
console.log(actualGrade);
}
// A, F, F, F, APairwise
Returns successive overlapping pairs.
Returns empty generator if given collection contains fewer than 2 elements.
function *pairwise<T>(data: Iterable<T>|Iterator<T>): Iterable<Pair<T>>import { single } from 'itertools-ts';
const friends = ['Ross', 'Rachel', 'Chandler', 'Monica', 'Joey', 'Phoebe'];
for (const [leftFriend, rightFriend] of single.pairwise(friends)) {
console.log(`${leftFriend} and ${rightFriend}`);
}
// Ross and Rachel, Rachel and Chandler, Chandler and Monica, ...Repeat
Repeat an item.
function *repeat<T>(item: T, repetitions: number): Iterable<T>import { single } from 'itertools-ts';
data = 'Beetlejuice';
repetitions = 3;
for (const repeated of single.repeat(data, repetitions)) {
console.log(repeated);
}
// 'Beetlejuice', 'Beetlejuice', 'Beetlejuice'Reduce
To Value
Reduce elements to a single value using reducer function.
function toValue<TInput, TOutput>(
data: Iterable<TInput>|Iterator<TInput>,
reducer: (carry: TOutput|undefined, datum: TInput) => TOutput,
initialValue?: TOutput,
): TOutput|undefinedimport { reduce } from 'itertools-ts';
const input = [1, 2, 3, 4, 5];
const sum = (carry, item) => carry + item;
const result = reduce.toValue(input, sum, 0);
// 15Set and multiset
Distinct
Filter out elements from the iterable only returning distinct elements.
function *distinct<T>(data: Iterable<T>|Iterator<T>): Iterable<T>import { set } from 'itertools-ts';
const chessSet = ['rook', 'rook', 'knight', 'knight', 'bishop', 'bishop', 'king', 'queen', 'pawn', 'pawn'];
for (const chessPiece of set.distinct(chessSet)) {
console.log(chessPiece);
}
// rook, knight, bishop, king, queen, pawnSummary
Is Iterable
Returns true if given data is an Iterable instance.
function isIterable(input: unknown): booleanimport { summary } from "itertools-ts";
const input = [1, 2, 3, 4, 5];
summary.isIterable(input); // true
summary.isIterable(input[Symbol.iterator]()) // false
summary.isIterable(1); // falseIs Iterator
Returns true if given data is an Iterator instance.
function isIterator(input: unknown): booleanimport { summary } from "itertools-ts";
const input = [1, 2, 3, 4, 5];
summary.isIterator(input[Symbol.iterator]()) // true
summary.isIterator(input); // false
summary.isIterator(1); // falseTransform
To Iterable
Returns Iterable instance of given collection or iterator.
Throws InvalidArgumentError if given data is not a collection or an iterator.
function toIterable<T>(collection: Iterable<T>|Iterator<T>): Iterable<T>import { transform } from "itertools-ts";
const input = [1, 2, 3, 4, 5];
const result = transform.toIterable(input);
// [1, 2, 3, 4, 5]To Array
Returns Array instance of given collection or iterator.
function toArray<T>(collection: Iterable<T>|Iterator<T>): Array<T>import { transform } from "itertools-ts";
const iterator = transform.toIterator([1, 2, 3, 4, 5]);
const result = transform.toArray(iterator);
// [1, 2, 3, 4, 5]To Iterator
Returns Iterator instance of given collection or iterator.
Throws InvalidArgumentError if given data is not a collection or an iterator.
function toIterator<T>(collection: Iterable<T>|Iterator<T>): Iterator<T>import { transform } from "itertools-ts";
const input = [1, 2, 3, 4, 5];
const result = transform.toIterator(input);
console.log(result.next !== undefined);
// trueStream
Stream Sources
Of
Creates stream from an iterable.
Stream.of(data: Iterable<unknown>|Iterator<unknown>): Streamimport { Stream } from "itertools-ts";
const iterable = [1, 2, 3];
const result = Stream.of(iterable)
.chainWith([4, 5, 6], [7, 8, 9])
.zipEqualWith([1, 2, 3, 4, 5, 6, 7, 8, 9])
.toArray();
// [[1, 1], [2, 2], [3, 3], [4, 4], [5, 5], [6, 6], [7, 7], [8, 8], [9, 9]]Of Empty
Creates stream of nothing.
Stream.ofEmpty(): Streamimport { Stream } from "itertools-ts";
const result = Stream.ofEmpty()
.chainWith([1, 2, 3])
.toArray();
// 1, 2, 3Stream Operations
Chain With
Return a stream chaining additional sources together into a single consecutive stream.
stream.chainWith(
...iterables: Array<Iterable<unknown>|Iterator<unknown>>
): Streamimport { Stream } from "itertools-ts";
const input = [1, 2, 3];
const result = Stream.of(input)
.chainWith([4, 5, 6])
.chainWith([7, 8, 9])
.toArray();
// 1, 2, 3, 4, 5, 6, 7, 8, 9Chunkwise
Return a stream consisting of chunks of elements from the stream.
stream.chunkwise(chunkSize: number): StreamChunk size must be at least 1.
import { Stream } from "itertools-ts";
const friends = ['Ross', 'Rachel', 'Chandler', 'Monica', 'Joey'];
const result = Stream.of(friends)
.chunkwise(2)
.toArray();
// ['Ross', 'Rachel'], ['Chandler', 'Monica'], ['Joey']Chunkwise Overlap
Return a stream consisting of overlapping chunks of elements from the stream.
chunkwiseOverlap(
chunkSize: number,
overlapSize: number,
includeIncompleteTail: boolean = true,
): Stream- Chunk size must be at least 1.
- Overlap size must be less than chunk size.
import { Stream } from "itertools-ts";
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9];
const result = Stream.of(numbers)
.chunkwiseOverlap(3, 1)
.toArray()
// [1, 2, 3], [3, 4, 5], [5, 6, 7], [7, 8, 9]Distinct
Return a stream filtering out elements from the stream only returning distinct elements.
stream.distinct(): Streamimport { Stream } from "itertools-ts";
const input = [1, 2, 1, 2, 3, 3, '1', '1', '2', '3'];
const stream = Stream.of(input)
.distinct()
.toArray();
// 1, 2, 3, '1', '2', '3'Filter
Filter out elements from the stream only keeping elements where there predicate function is true.
filter(predicate: (item: unknown) => boolean): Streamimport { Stream } from "itertools-ts";
const input = [1, -1, 2, -2, 3, -3];
const result = Stream.of(input)
.filter((value) => value > 0)
.toArray();
// 1, 2, 3Flat Map
Map a function onto the elements of the stream and flatten the results.
stream.flatMap(mapper: (datum: unknown) => unknown): Streamimport { Stream } from "itertools-ts";
const data = [1, 2, 3, 4, 5];
const mapper = (item) => (item % 2 === 0) ? [item, item] : item;
const result = Stream.of(data)
.flatMap(mapper)
.toArray();
// [1, 2, 2, 3, 4, 4, 5]Flatten
Flatten a multidimensional stream.
stream.flatten(dimensions: number = Infinity): Streamimport { Stream } from "itertools-ts";
const data = [1, [2, 3], [4, 5]];
const result = Stream.of(data)
.flatten()
.toArray();
// [1, 2, 3, 4, 5]Limit
Return a stream up to a limit.
Stops even if more data available if limit reached.
limit(count: number): Streamimport { Stream } from "itertools-ts";
const matrixMovies = ['The Matrix', 'The Matrix Reloaded', 'The Matrix Revolutions', 'The Matrix Resurrections'];
const limit = 1;
const goodMovies = Stream.of(matrixMovies)
.limit(limit)
.toArray();
// 'The Matrix' (and nothing else)Map
Return a stream containing the result of mapping a function onto each element of the stream.
stream.map(mapper: (datum: unknown) => unknown): Streamimport { Stream } from "itertools-ts";
const grades = [100, 95, 98, 89, 100];
const result = Stream.of(grades)
.map((grade) => grade === 100 ? 'A' : 'F')
.toArray();
// A, F, F, F, APairwise
Return a stream consisting of pairs of elements from the stream.
stream.pairwise(): StreamReturns empty stream if given collection contains less than 2 elements.
import { Stream } from "itertools-ts";
const input = [1, 2, 3, 4, 5];
const stream = Stream.of(input)
.pairwise()
.toArray();
// [1, 2], [2, 3], [3, 4], [4, 5]Zip With
Return a stream consisting of multiple iterable collections streamed simultaneously.
stream.zipWith(
...iterables: Array<Iterable<unknown>|Iterator<unknown>>
): StreamFor uneven lengths, iterations stops when the shortest iterable is exhausted.
import { Stream } from "itertools-ts";
const input = [1, 2, 3];
const stream = Stream.of(input)
.zipWith([4, 5, 6])
.toArray();
// [1, 4], [2, 5], [3, 6]Zip Longest With
Return a stream consisting of multiple iterable collections streamed simultaneously.
stream.zipLongestWith(
...iterables: Array<Iterable<unknown>|Iterator<unknown>>
): Stream- Iteration continues until the longest iterable is exhausted.
- For uneven lengths, the exhausted iterables will produce
undefinedfor the remaining iterations.
import { Stream } from "itertools-ts";
const input = [1, 2, 3, 4, 5];
const stream = Stream.of(input)
.zipLongestWith([4, 5, 6]);
for (const zipped of stream) {
// [1, 4], [2, 5], [3, 6], [4, undefined], [5, undefined]
}Zip Equal With
Return a stream consisting of multiple iterable collections of equal lengths streamed simultaneously.
zipEqualWith(
...iterables: Array<Iterable<unknown>|Iterator<unknown>>
): StreamWorks like Stream.zipWith() method but throws LengthException if lengths not equal,
i.e., at least one iterator ends before the others.
import { Stream } from "itertools-ts";
const input = [1, 2, 3];
const stream = Stream.of(input)
.zipEqualWith([4, 5, 6]);
for (const zipped of stream) {
// [1, 4], [2, 5], [3, 6]
}Terminal operations
Transformation Terminal Operations
To Array
Returns an array of stream elements.
stream.toArray(): Array<unknown>import { Stream } from "itertools-ts";
const result = Stream.of([1, 2, 3, 4, 5])
.map((x) => x**2)
.toArray();
// [1, 4, 9, 16, 25]Reduce Terminal Operations
To Value
Reduces iterable source like array_reduce() function.
toValue<T>(
reducer: (carry: T|undefined, datum: unknown) => T,
initialValue?: T,
): T|undefinedimport { Stream } from "itertools-ts";
const input = [1, 2, 3, 4, 5];
const result = Stream.of(input)
.toValue((carry, item) => carry + item);
// 15Unit testing
npm i
npm run testLicense
IterTools TS is licensed under the MIT License.
