iterator-helper
Provide helpers that polyfill all methods defined in iterator helpers proposal, both for Iterator
and AsyncIterator
, and even more.
Installation
Install it with npm/yarn/what you want.
npm i iterator-helper
Getting started
You can wrap an iterable or an iterator with the exported iter
(for standard iterables) and aiter
(for async iterables) functions.
import { iter, aiter } from 'iterator-helper';
const iterator = iter([1, 2, 3]);
const mapped_cycle = iterator
.cycle()
.map(e => e * 2)
.asIndexedPairs();
for (const [index, element] of mapped_cycle) {
console.log(index, element);
}
You can also extend two exported classes, HIterator
and HAsyncIterator
(those names are used to avoid conflicts with possible futures Iterator
and AsyncIterator
global objects), in order to make your classes iterables.
import { HIterator } from 'iterator-helper';
class RangeIterator extends HIterator {
constructor(start, stop = undefined, step = 1) {
super();
this.position = stop === undefined ? 0 : start;
this.stop = stop === undefined ? start : stop;
this.step = step;
if (stop < start) {
throw new Error('Stop cannot be inferior to start.');
}
if (step <= 0) {
throw new Error('Step must be superior to 0.');
}
}
next() {
if (this.position < this.stop) {
const current = this.position;
this.position += this.step;
return { value: current, done: false };
}
return { value: undefined, done: true };
}
}
const range = new RangeIterator(10).filter(e => e % 2 === 0);
range.next();
range.next();
range.next();
Generators helpers
If you have some (a)sync generators, you can wrap them with the appropriate wrapper:
import { wrap, awrap } from 'iterator-helper';
function* generateNumbers() {
yield 1;
yield* [2, 3, 4];
}
generateNumbers = wrap(generateNumbers);
generateNumbers().filter(e => e % 2 === 0).toArray();
API
As the proposal purpose, there are a few methods for each prototype. They're presented here with TypeScript types.
interface HIterator<T, TReturn = any, TNext = undefined> {
map<R>(callback: (value: T) => R) : HIterator<R, TReturn, TNext>;
filter(callback: (value: T) => boolean) : HIterator<T, TReturn, TNext>;
take(limit: number) : HIterator<T, TReturn, TNext>;
drop(limit: number) : HIterator<T, TReturn, TNext>;
asIndexedPairs() : HIterator<[number, T], TReturn, TNext>;
flatMap<R>(mapper: (value: T) => Iterator<R> | R) : HIterator<R, TReturn, TNext>;
find(callback: (value: T) => boolean) : T | undefined;
every(callback: (value: T) => boolean) : boolean;
some(callback: (value: T) => boolean) : boolean;
toArray(max_count?: number) : T[];
reduce<V>(reducer: (acc: V, value: T) => V, initial_value?: V) : V;
forEach(callback: (value: T) => any) : void;
count() : number;
join(glue: string) : string;
chain<I>(...iterables: IterableIterator<I>[]) : HIterator<T | I>;
zip<O>(...others: IterableIterator<O>[]) : HIterator<(T | O)[]>;
takeWhile(callback: (value: T) => boolean) : HIterator<T>;
dropWhile(callback: (value: T) => boolean) : HIterator<T>;
fuse() : HIterator<T>;
partition(callback: (value: T) => boolean) : [T[], T[]];
findIndex(callback: (value: T) => boolean) : number;
max() : number;
min() : number;
cycle() : HIterator<T>;
}
interface HAsyncIterator<T, TReturn = any, TNext = undefined> {
map<R>(callback: (value: T) => R) : HAsyncIterator<R, TReturn, TNext>;
filter(callback: (value: T) => boolean) : HAsyncIterator<T, TReturn, TNext>;
take(limit: number) : HAsyncIterator<T, TReturn, TNext>;
drop(limit: number) : HAsyncIterator<T, TReturn, TNext>;
asIndexedPairs() : HAsyncIterator<[number, T], TReturn, TNext>;
flatMap<R>(mapper: (value: T) => AsyncIterator<R> | R) : HAsyncIterator<R, TReturn, TNext>;
find(callback: (value: T) => boolean) : Promise<T | undefined>;
every(callback: (value: T) => boolean) : Promise<boolean>;
some(callback: (value: T) => boolean) : Promise<boolean>;
toArray(max_count?: number) : Promise<T[]>;
reduce<V>(reducer: (acc: V, value: T) => V, initial_value?: V) : Promise<V>;
forEach(callback: (value: T) => any) : Promise<void>;
count() : Promise<number>;
join(glue: string) : Promise<string>;
chain<I>(...iterables: IterableIterator<I>[]) : HAsyncIterator<T | I>;
zip<O>(...others: IterableIterator<O>[]) : HAsyncIterator<(T | O)[]>;
takeWhile(callback: (value: T) => boolean) : HAsyncIterator<T>;
dropWhile(callback: (value: T) => boolean) : HAsyncIterator<T>;
fuse() : HAsyncIterator<T>;
partition(callback: (value: T) => boolean) : Promise<[T[], T[]]>;
findIndex(callback: (value: T) => boolean) : Promise<number>;
max() : Promise<number>;
min() : Promise<number>;
cycle() : HAsyncIterator<T>;
}
A few more methods has been implemented, but they're not part of the specification. See index.ts
to see them inside the Iterator
and AsyncIterator
interface.