All files / iterable/src zip.ts

100% Statements 11/11
100% Branches 1/1
100% Functions 5/5
100% Lines 8/8

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 40 41                                              17x     17x 33x     17x 59x   42x 9x     42x      
type ExtractValue<T extends ReadonlyArray<Iterable<unknown>>> = {
  [K in keyof T]: T[K] extends Iterable<infer V> ? V : never;
};
 
/**
 * Creates an {@link Iterable} of grouped elements from multiple {@link Iterable}s.
 *
 * @example
 * ```ts
 * const iterable1 = [1, 2, 3];
 * const iterable2 = ["a", "b"];
 *
 * const iterable = zip(iterable1, iterable2);
 *
 * console.log(iterable); // [1, "a"], [2, "b"], [3, undefined]
 * ```
 *
 * @see {@link chunk}, {@link concat}, {@link flatMap} and {@link pairwise} for
 * similar operations.
 *
 * @param iterables - the {@link Iterable}s to zip
 * @returns - the zipped {@link Iterable}
 */
export function* zip<RArgs extends Iterable<unknown>[]>(
  ...iterables: RArgs
): Iterable<ExtractValue<RArgs>> {
  const iterators = iterables.map<Iterator<unknown, unknown>>((iterable) =>
    iterable[Symbol.iterator]()
  );
 
  while (true) {
    const iteratorResults = iterators.map((iterator) => iterator.next());
 
    if (iteratorResults.every((result) => result.done)) {
      return;
    }
 
    yield iteratorResults.map((result) => result.value) as ExtractValue<RArgs>;
  }
}