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
reducewhen you are simply selecting one existing item from the array. - Throws
TypeErrorif the input is not an array or if the array is empty.