All files / array/src findAndThen.ts

100% Statements 6/6
100% Branches 3/3
100% Functions 4/4
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  3x                                                       5x 3x       5x 6x 6x    
import { Predicate } from "@benneq/predicate";
import { findIndex } from "./findIndex";
 
type FindAndThen = {
  <T, R, A extends ArrayLike<T> = ArrayLike<T>>(
    thenCallback: (value: T, index: number, array: A) => R
  ): (
    predicate: Predicate<[T, number, A]>,
    fromIndex?: number
  ) => (array: A) => R | undefined;
  <T, R, A extends ArrayLike<T> = ArrayLike<T>>(
    thenCallback: (value: T, index: number, array: A) => R,
    defaultValue: R
  ): (
    predicate: Predicate<[T, number, A]>,
    fromIndex?: number
  ) => (array: A) => R;
};
 
/**
 * Calls a callback function for the first element of an {@link Array} that
 * matches a {@link Predicate}.
 *
 * Returns `undefined` if no match was found and no `defaultValue` was provided.
 *
 * @param thenCallback
 * @param defaultValue - the optional default value to return
 * @returns the return value of the callback if the {@link Predicate} did match, otherwise the `defaultValue`
 */
export const findAndThen: FindAndThen =
  <T, R>(
    thenCallback: (value: T, index: number, array: T[]) => R,
    defaultValue?: R
  ) =>
  (predicate: Predicate<[T, number, ArrayLike<T>]>, fromIndex?: number) =>
  (array: T[], i = findIndex(predicate, fromIndex)(array)): R | undefined => {
    return i < 0 ? defaultValue : thenCallback(array[i] as T, i, array);
  };