All files / comparator/src chain.ts

100% Statements 8/8
100% Branches 2/2
100% Functions 3/3
100% Lines 7/7

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                                                    2x 2x 4x 3x 3x 2x     2x      
import { Comparator } from "./_types";
 
/**
 * Executes {@link Comparator}s in order and returns the first non-zero result.
 *
 * @example
 * Sort objects first by age and then by name
 * ```ts
 * const personComparator = chain<Person>(
 *   mappingComparator(numberComparator)(p => p.age),
 *   mappingComparator(stringComparator)(p => p.name)
 * );
 *
 * const array: Person[] = [
 *   { age: 1, name: "B" },
 *   { age: 1, name: "A" }
 * ];
 *
 * array.sort(personComparator);
 * console.log(array); // [{age:1, name:"A"}, {age:1, name:"B"}]
 * ```
 *
 * @typeParam T - the {@link Comparator} value type
 * @param comparators - the {@link Comparator}s to chain
 * @returns the result of the first {@link Comparator} that is not `0`, or else `0`
 */
export const chain = <T>(...comparators: Comparator<T>[]): Comparator<T> => {
  return (valueA, valueB, result = 0) => {
    for (const comparator of comparators) {
      result = comparator(valueA, valueB);
      if (result) {
        return result;
      }
    }
    return 0;
  };
};