All files / iterable/src iterate.ts

100% Statements 6/6
100% Branches 1/1
100% Functions 1/1
100% Lines 6/6

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39  1x                                                   2x         2x 2x 7x 7x      
import { Mapper } from "@benneq/function";
import { alwaysTrue, Predicate } from "@benneq/predicate";
 
/**
 * Creates an {@link Iterable} that emits a sequence of values computed by a
 * {@link Mapper} function, starting with a `seed` value. The sequence ends
 * when the `hasNext` {@link Predicate} returns `false`.
 *
 * @example
 * Iterate from `1` to `3`
 * ```ts
 * const iterable = iterate(
 *   1,
 *   x => x + 1,
 *   x => x < 3
 * );
 *
 * console.log(iterable); // [1, 2, 3]
 * ```
 *
 * @see {@link generate} for similar operations.
 *
 * @typeParam T - the {@link Iterable} value type
 * @param seed - the first value of the sequence
 * @param next - the {@link Mapper} function to compute the next value
 * @param hasNext - the {@link Predicate} to check if there's a next value
 */
export function* iterate<T>(
  seed: T,
  next: Mapper<T, T>,
  hasNext: Predicate<[T]> = alwaysTrue
): IterableIterator<T> {
  yield seed;
  while (hasNext(seed)) {
    seed = next(seed);
    yield seed;
  }
}