iteragain
Version:
Javascript Iterable/Iterator/Generator-function utilities.
347 lines • 19 kB
TypeScript
import { IteratorOrIterable, FlattenDeep, FlattenDepth1, FlattenDepth2, FlattenDepth3, FlattenDepth4, FlattenDepth5, Tuple, Predicate, Iteratee, IterSource, Callback, StrictPredicate, Awaited, KeyIdentifier, KeyIdentifiersValue, UniqueParams } from '../types';
/**
* Extends and implements the IterableIterator interface. Methods marked with the `@lazy` prefix are chainable methods
* that modify the internal iterator, but don't start iterating. Methods without the `@lazy` prefix do start iterating
* some amount, depending on the method.
*/
export declare class ExtendedIterator<T> implements IterableIterator<T> {
protected iterator: Iterator<T>;
constructor(iterator: Iterator<T>);
/** Returns a `{ value, done }` object that adheres to the Iterator interface. */
next(...args: any[]): IteratorResult<T, T>;
/** Implements this as an Iterable so it's allowed to be used with "for of" loops. */
[Symbol.iterator](): this;
toString(): string;
/** @lazy Returns a new ExtendedIterator that maps each element in this iterator to a new value. */
map<R>(iteratee: Iteratee<T, R>): ExtendedIterator<R>;
/**
* @lazy
* Returns a new ExtendedIterator that filters each element in this iterator.
* @param predicate A function that returns a truthy value to indicate to keep that value.
*/
filter(predicate: BooleanConstructor): ExtendedIterator<NonNullable<T>>;
filter<S extends T>(predicate: StrictPredicate<T, S>): ExtendedIterator<S>;
filter(predicate: Predicate<T>): ExtendedIterator<T>;
/**
* @lazy
* Maps and filters the input iterator in the same `iteratee` function.
* @param iteratee A function that maps each value in this iterator to a new value and also filters out any that
* return a nullish value.
*/
filterMap<R>(iteratee: Iteratee<T, R>): ExtendedIterator<NonNullable<R>>;
/** @lazy Concatenates this iterator with the given iterators, in order of: `[this.iterator, ...others]`. */
concat<U extends IteratorOrIterable<any>[]>(...args: U): ExtendedIterator<T | IterSource<U[number]>>;
/** @lazy Prepends this iterator with the given iterators, in order of: `[...args, this.iterator]`. */
prepend<U extends IteratorOrIterable<any>[]>(...args: U): ExtendedIterator<T | IterSource<U[number]>>;
/**
* @lazy
* Works like `Array.prototype.slice`, returns a new slice of this iterator.
* @note This does not support negative `start` and `end` indices, as it's not possible to know the length of the
* iterator while iterating.
* @param start The index to start at (inclusive).
* @param end The index to end at (exclusive).
* @returns A new ExtendedIterator that only includes the elements between `start` and `end`.
*/
slice(start?: number, end?: number): ExtendedIterator<T>;
/**
* @lazy
* Flatten this iterator by a known depth or deeply.
* @param depth The number of levels to flatten (default: Infinity, i.e. deeply).
*/
flatten(depth: 1): ExtendedIterator<FlattenDepth1<T>>;
flatten(depth: 2): ExtendedIterator<FlattenDepth2<T>>;
flatten(depth: 3): ExtendedIterator<FlattenDepth3<T>>;
flatten(depth: 4): ExtendedIterator<FlattenDepth4<T>>;
flatten(depth: 5): ExtendedIterator<FlattenDepth5<T>>;
flatten(): ExtendedIterator<FlattenDeep<T>>;
flatten(depth: number): ExtendedIterator<any>;
/** @lazy Attaches the index to each value as a pair like: `[0, value], [1, value]`, etc. */
enumerate(): ExtendedIterator<[number, T]>;
/**
* @lazy
* The inverse of `zip` and `zipLongest`. This method disaggregates the elements of this iterator. The nth iterator
* in the returned tuple contains the nth element of each value in this iterator. The length of the returned tuple is
* determined by the length of the first value in this iterator.
*/
unzip(): ExtendedIterator<T>[];
/** @lazy Aggregates this iterator and any number of others into one. Stops when one of the iterables is empty. */
zip<U>(other: IteratorOrIterable<U>): ExtendedIterator<[T, U]>;
zip<A, B>(a: IteratorOrIterable<A>, b: IteratorOrIterable<B>): ExtendedIterator<[T, A, B]>;
zip(...args: IteratorOrIterable<any>[]): ExtendedIterator<any[]>;
/** @lazy Aggregates this iterator and any number of others into one. Stops when all of the iterables is empty. */
zipLongest<U>(other: IteratorOrIterable<U>): ExtendedIterator<[T, U]>;
zipLongest<A, B>(a: IteratorOrIterable<A>, b: IteratorOrIterable<B>): ExtendedIterator<[T, A, B]>;
zipLongest(...args: IteratorOrIterable<any>[]): ExtendedIterator<any[]>;
/**
* @lazy
* Return a new iterator of pairs (tuples) of the values in this one. The number of pairs will always be one fewer
* than this iterator. Will be empty if this iterator has fewer than two values.
* @example
* iter([1,2,3]).pairwise().toArray() // [[1,2], [2,3]]
* iter([1]).pairwise().toArray() // []
*/
pairwise(): ExtendedIterator<[T, T]>;
/**
* @lazy
* Returns a new iterator of triplets (tuples) of the values in this one. The number of triplets will always be two
* fewer than the number of values in this iterator. Will be empty if this iterator has fewer than three values.
*/
triplewise(): ExtendedIterator<[T, T, T]>;
/**
* @lazy
* Take all elements from this iterator while the given `predicate` returns a truthy value.
* @param predicate A function to call for each value.
*/
takeWhile(predicate: Predicate<T>): ExtendedIterator<T>;
/**
* @lazy
* Drop/skip values in this iterator while the passed `predicate` returns a truthy value.
* @param predicate The function to call for each value.
*/
dropWhile(predicate: Predicate<T>): ExtendedIterator<T>;
/**
* @lazy
* Tap into this iterator by supplying `func` which is passed each value of this iterator. The return value of
* func is unused and this method is purely designed for a designated place to perform side effects.
* @example
* iter([1,2,3])
* .tap(console.log) // logs 1, 2, 3 to the console
* .map(n => n * n)
* .tap(console.log) // logs 1, 4, 9 to the console
* .toArray() // returns [1, 4, 9]
*/
tap(func: Predicate<T>): ExtendedIterator<T>;
/**
* @lazy
* Yields non-overlapping chunks (tuples) of `length` from this iterator.
* @param length The length of each chunk, must be greater than 0.
* @param fill Optional, the value to fill the last chunk with if it's not the same length as the rest of the iterator.
* @example
* iter([1,2,3,4,5,6,7,8,9]).chunk(3).toArray() // [[1,2,3], [4,5,6], [7,8,9]]
* iter([1,2,3,4,5,6,7,8,9]).chunk(2, 0).toArray() // [[1,2], [3,4], [5,6], [7,8], [9, 0]]
*/
chunks<Length extends number>(length: Length, fill?: T): ExtendedIterator<Tuple<T, Length>>;
/**
* @lazy
* Yields sliding windows (tuples) of `length` from this iterator. Each window is separated by `offset` number of
* elements.
* @param length The length of each window, must be greater than 0.
* @param offset The offset of each window from each other. Must be greater than 0.
* @param fill Optional, the value to fill the last window with if it's not the same length as the rest of the iterator.
* @example
* iter([1,2,3,4,5]).windows(2, 1).toArray() // [[1,2], [2,3], [3,4], [4,5]]
* iter([1,2,3,4,5]).windows(2, 3).toArray() // [[1,2], [4,5]]
* iter([1,2,3,4,5]).windows(3, 3, 0).toArray() // [[1,2,3], [4,5,0]]
*/
windows<Length extends number>(length: Length, offset: number, fill?: T): ExtendedIterator<Tuple<T, Length>>;
/**
* @lazy
* Returns `n` independent iterators, each of which is a copy of this iterator at the time of calling `tee`. Once
* `tee` has made a split, do not modify or call upon the original iterator, as the new iterators will not be
* updated/informed.
* This caches the original iterator's values as the new iterators are iterated through. So
* depending on the size of the original iterator, there could be significant memory overhead in using `tee`.
* `tee`'s intended use is to iterate over the returned iterators in parallel, or at least somewhat in parallel. In
* general, if one returned iterator consumes most or all of it's values, then it is faster to just
* use `toArray` and then iterate over that.
* @param n The number of independent iterators to create.
*/
tee<N extends number>(n: N): Tuple<ExtendedIterator<T>, N>;
/**
* @lazy
* Makes this iterator cycle infinitely through it's values.
* @param times The number of times to cycle through the iterator (default: Infinity).
* @example
* equal(iter([1,2,3]).cycle().take(5).toArray(), [1,2,3,1,2])
*/
cycle(times?: number): ExtendedIterator<T>;
/**
* @lazy
* Resumes this iterator a certain number of times after it's next value returns `{ done: true }`.
* @param times The number of times to resume the iterator (default: Infinity).
* @example
* const it = iter([1,2,3]).resume(1);
* equal(it.toArray(), [1,2,3]);
* equal(it.toArray(), [1,2,3]);
* equal(it.toArray(), []);
*/
resume(times?: number): ExtendedIterator<T>;
/**
* @lazy
* Filters/compresses this iterator to only values that correspond to truthy values in `selectors`.
* @param selectors An iterator or iterable of falsey or truthy values to select which values to keep in this
* iterator.
*/
compress(selectors: IteratorOrIterable<any>): ExtendedIterator<T>;
/**
* @lazy
* Returns all successive `size` length permutations of this iterator. The permutations are emitted in lexicographic
* ordering according to this iterator. So if this iterator is sorted, the permutations will be in sorted order.
* Elements in the permutations are treated as unique based on their position in the iterator, not on their value. So
* if the input iterator is unique, then there will be no repeat values.
* @see https://docs.python.org/3/library/itertools.html#itertools.permutations for more info.
* @param size The size of each permutation, must be greater than 0 and less than or equal to the length of this
* iterator.
*/
permutations<Size extends number>(size?: Size): ExtendedIterator<Tuple<T, Size>>;
/**
* @lazy
* Returns `size` length subsequences of this iterator.
* @see https://docs.python.org/3/library/itertools.html#itertools.combinations for more info.
* @see https://docs.python.org/3/library/itertools.html#itertools.combinations_with_replacement for more info.
* @param size The size of each combination.
* @param withReplacement Whether or not to allow duplicate elements in the combinations.
*/
combinations<Size extends number>(size: Size, withReplacement?: boolean): ExtendedIterator<Tuple<T, Size>>;
/**
* @lazy
* Returns the cartesian product of this iterator with other `iterators` after it.
* @param iterators Other iterators.
* @param repeat Optional number of times to repeat (default: 1).
* @see https://docs.python.org/3/library/itertools.html#itertools.product for more info.
*/
product(repeat?: number): ExtendedIterator<T[]>;
product(iterators: IteratorOrIterable<T>[], repeat?: number): ExtendedIterator<T[]>;
/**
* @lazy
* Filters this iterator to only unique values.
* @param iteratee Iteratee to use to transform each value before being tested for uniqueness.
* @param justSeen If true, will only test for uniqueness with the last value in the iterator and not all values.
*/
unique(params?: UniqueParams<T>): ExtendedIterator<T>;
/**
* @lazy
* Reverses this iterator's order. Note that in order to reverse, it will attempt to iterate fully once, which
* could cause significant memory usage. So because of this, only use on finite iterators.
*/
reverse(): ExtendedIterator<T>;
/** @lazy Maps `key` from `T` in each value of this iterator. */
pluck<K extends keyof T>(key: K): ExtendedIterator<T[K]>;
/** Reduces this iterator to a single value. */
reduce(reducer: (accumulator: T, value: T) => T): T;
reduce<R>(reducer: (accumulator: R, value: T) => R, initialValue: R): R;
reduce<R>(reducer: (accumulator: T | R, value: T) => R): R;
/** Consumes this iterator and returns the number of values/items in it. */
length(): number;
/** Returns the number of times the `predicate` returns a truthy value. */
quantify(predicate: Predicate<T>): number;
/** Returns the minimum value from this iterator. */
min(iteratee?: Iteratee<T, number>): T;
/** Returns the maximum value from this iterator. */
max(iteratee?: Iteratee<T, number>): T;
/** Returns the minimum and maximum from this iterator as a tuple: `[min, max]`. */
minmax(iteratee?: Iteratee<T, number>): [T, T];
/** Iterate over this iterator using the `array.prototype.forEach` style of method. */
forEach(callback: Callback<T>): void;
/** Return true if every element in this iterator matches the predicate. */
every(predicate: Predicate<T>): boolean;
/** Return true if only one element in this iterator matches the predicate. */
some(predicate: Predicate<T>): boolean;
/**
* Returns this iterator as a string with each value joined by `separator`.
* @param separator The separator to use between each value (default: ',').
*/
join(separator?: string): string;
/**
* Finds the first value that passes a truthy value to `predicate`, then returns it. Only consumes the iterator's
* values up to the found value, then stops. So if it's not found, then the iterator is exhausted.
*/
find<V extends T>(predicate: (value: T) => value is V): V | undefined;
find(predicate: Predicate<T>): T | undefined;
/**
* Finds the index of the first value that passes a truthy vale to `predicate`, then returns it. Only consumes the
* iterator's values up to the found value, then stops. So if it's not found, then the iterator is exhausted.
*/
findIndex(predicate: Predicate<T>): number;
/**
* Maps this iterator to a new value `R` and flattens any resulting iterables or iterators by a depth of 1.
* Behaves the same as `Array.prototype.flatMap`.
*/
flatMap<R>(iteratee: Iteratee<T, R | IteratorOrIterable<R>>): ExtendedIterator<R>;
/** Returns true if `value` strictly equals some value in this iterator. */
includes(value: T): boolean;
/**
* Peek ahead of where the current iteration is. This doesn't consume any values of the iterator.
* @param ahead optional, the number of elements to peek ahead.
*/
peek<N extends number = 1>(ahead?: N): Tuple<T, N>;
/**
* Take `n` number of values from this iterator.
* @param n The number of values to take.
*/
take<N extends number = 1>(n?: N): Tuple<T, N>;
/**
* @deprecated Use `consume` instead, as this is the more standard name for this type of method.
* Start iterating through this iterator, but don't return the values from this method.
* @param n optional, the number of elements to exhaust.
*/
exhaust(n?: number): void;
/**
* Start iterating through this iterator, but don't return the values from this method.
* @param n optional, the number of elements to consume (default: Infinity).
*/
consume(n?: number): void;
/**
* Collects all values from this iterator, then shuffles the order of it's values.
* @param seed A seed between 0 and 1.
*/
shuffle(seed?: number): ExtendedIterator<T>;
/** Collects all values from this iterator, then sorts them. */
sort(comparator?: (a: T, b: T) => number): ExtendedIterator<T>;
/**
* Partitions this iterator into a tuple of `[falsey, truthy]` corresponding to what `predicate` returns for each
* value.
*/
partition(predicate: Predicate<T>): [falsey: T[], truthy: T[]];
/**
* @lazy
* Distributes this iterator's values among `n` amount of smaller iterators. Does not maintain order so if order is
* important, use `divide` instead.
*/
distribute<Size extends number>(n: Size): Tuple<ExtendedIterator<T>, Size>;
/**
* Groups *consecutive* keys in the input iterator by some key identifier function or property. Functionally equivalent
* to the itertools.groupby function in Python. Generally the input iterator needs to be sorted by the same key. Each
* iteration will return the next group of values with the same key, until the key changes. So unless the input iterator
* is sorted beforehand, you may have broken up groups with the same keys.
* @param arg The input iterator or iterable.
* @param key The key identifier function or property name. If left undefined, and the value is a primitive, the value
* itself is used as a key. Iterators for object like values *must* use a key identifier.
* @example
* groupby('AAAABBBCCDAABBB') // =>
* // ['A', ['A', 'A', 'A', 'A']],
* // ['B', ['B', 'B', 'B']],
* // ['C', ['C', 'C']],
* // ['D', ['D']],
* // ['A', ['A', 'A']],
* // ['B', ['B', 'B', 'B']]
*/
groupBy(): ExtendedIterator<[T, T[]]>;
groupBy<K extends KeyIdentifier<T>>(key: K): ExtendedIterator<[KeyIdentifiersValue<T, K>, T[]]>;
/**
* Divides this iterator into `n` amount of smaller iterators while maintaining order. Note, this method will fully
* iterate through this iterator before returning a result. If you don't want this behavior and don't care about
* order then use `distribute` instead.
*/
divide<Size extends number>(n: Size): Tuple<ExtendedIterator<T>, Size>;
/**
* Iterates and finds the element at `index`. Returns undefined if not found.
* @param index The index to find. Only supports positive indices.
*/
nth(index: number): T | undefined;
/** Iterates and collects all values into an Array. */
toArray(): T[];
/** Calls `Promise.all` on all collected values. */
promiseAll(): Promise<Awaited<T>[]>;
/** Calls `Promise.race` on all collected values. */
promiseRace(): Promise<Awaited<T>>;
/** Shorthand for `new Set(this)`. */
toSet(): Set<T>;
/**
* Shorthand for `new Map<K, V>(this)`. The type of this iterator must extend `any[]` for this to work. And you may
* also need to pass in your own values for the generics: e.g. `iterator.toMap<string, number>();`
*/
toMap<K extends string | number = T extends any[] ? T[0] : never, V = T extends any[] ? T[1] : never>(): Map<K, V>;
}
export default ExtendedIterator;
//# sourceMappingURL=ExtendedIterator.d.ts.map