Skip to content
VersionSize

boil

The boil utility reduces an array to a single "best" value based on a custom comparison function. It is a specialized version of a "winner-takes-all" reduction, ideal for finding maximums, minimums, or other extreme values based on complex logic.

Implementation

View Source Code
ts
import { assert } from '../function/assert';
import { IS_ARRAY_ERROR_MSG, isArray } from '../typed/isArray';

/**
 * Boils down an array to a single value by applying a callback function to each pair of elements.
 *
 * @example
 * ```ts
 * boil([1, 2, 3]) // 3
 * boil([1, 2, 3], (a, b) => a > b ? a : b) // 3
 * boil([1, 2, 3], (a, b) => a + b) // 6
 * boil([{ a: 1 }, { a: 2 }, { a: 3 }], (a, b) => ({ a: a.a + b.a })) // { a: 6 }
 * boil([], (a, b) => a + b) // undefined
 * boil([1], (a, b) => a + b) // 1
 * ```
 *
 * @param array - The array to be boiled down.
 * @param callback - The function to invoke for each pair of elements in the array.
 *
 * @return The boiled down value, or `undefined` if the array is empty.
 */
export function boil<T>(array: readonly T[], callback: (a: T, b: T) => T): T | undefined {
  assert(isArray(array), IS_ARRAY_ERROR_MSG, {
    args: { array, callback },
    type: TypeError,
  });

  const fn = callback;

  let result = array[0];
  for (let i = 1; i < array.length; i++) {
    result = fn(result, array[i]);
  }
  return result;
}

Features

  • Isomorphic: Works in both Browser and Node.js.
  • Comparison-based: Unlike reduce, it focuses on choosing between two elements at a time.
  • Type-safe: Properly infers the return type from the array elements.

API

ts
function boil<T>(array: T[], callback: (item: T) => number, initial?: number): number;

Parameters

  • array: The array to process.
  • compare: A function that receives two elements and must return the one that should "win" (the one to keep).

Returns

  • The single value that remained after all comparisons.
  • Throws an error if the array is empty.

Examples

Finding the Longest String

ts
import { boil } from '@vielzeug/toolkit';

const fruits = ['apple', 'banana', 'cherry', 'date'];

const longest = boil(fruits, (a, b) => (a.length > b.length ? a : b));
// 'banana'

Complex Object Selection

ts
import { boil } from '@vielzeug/toolkit';

const users = [
  { name: 'Alice', score: 100 },
  { name: 'Bob', score: 150 },
  { name: 'Charlie', score: 120 },
];

const highScorer = boil(users, (a, b) => (a.score > b.score ? a : b));
// { name: 'Bob', score: 150 }

Implementation Notes

  • Performance is $O(n)$ where $n$ is the length of the array.
  • It is more semantically expressive than reduce when you are simply selecting one existing item from the array.
  • Throws TypeError if the input is not an array or if the array is empty.

See Also

  • max: Specialized boil for finding the maximum number.
  • min: Specialized boil for finding the minimum number.
  • reduce: The general-purpose reduction utility.