All files / iterable/src iterableComparator.ts

100% Statements 11/11
100% Branches 2/2
100% Functions 3/3
100% Lines 10/10

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 42 43 44 45 46 47 48 49 50 51 52 531x 1x                                                             11x     11x   11x           11x 15x 15x 8x     3x      
import { Comparator, undefinedFirst } from "@benneq/comparator";
import { zip } from "./zip";
 
/**
 * Creates a {@link Comparator} that compares the elements of two
 * {@link Iterable}s pairwise.
 *
 * Finds the first unequal pair and returns the result
 *
 * If all pairs are equal, the number of elements of the {@link Iterable}s will
 * be used for the comparison result.
 *
 * @example
 * Compare {@link Iterable}s of numbers
 * ```ts
 * const numberIterableComparator = iterableComparator(numberComparator);
 * const result = numberIterableComparator([1, 2], [1, 1]);
 * console.log(result); // 1
 * ```
 *
 * @example
 * Compare {@link Iterable}s with different lengths
 * ```ts
 * const numberIterableComparator = iterableComparator(numberComparator);
 * const result = numberIterableComparator([1, 1], [2]);
 * console.log(result); // 1
 * ```
 *
 * @typeParam T - the {@link Iterable} value type
 * @param comparator - the {@link Comparator} to use for the comparison of the elements
 * @returns a {@link Comparator} for {@link Iterable}s of type `T`
 */
export const iterableComparator = <T>(
  comparator: Comparator<T>
): Comparator<Iterable<T>> => {
  comparator = undefinedFirst(comparator);
 
  return (
    iterableA,
    iterableB,
    // internal variables:
    result = 0
  ) => {
    for (const [valueA, valueB] of zip(iterableA, iterableB)) {
      result = comparator(valueA, valueB);
      if (result) {
        return result;
      }
    }
    return 0;
  };
};