UNPKG

iteragain

Version:

Javascript Iterable/Iterator/Generator-function utilities.

347 lines 19 kB
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