Numerical
import { min, max, sum, subtract, product, average, hasEvenLength, median, mode, range, variance, standardDeviation, quantile, cumulativeSum, minBy, maxBy, sumBy, averageBy,} from 'op-array/numerical';min(values) / max(values)
min([3, 1, 2]); // 1max([3, 1, 2]); // 3sum(values)
Returns 0 for empty arrays.
sum([1, 2, 3]); // 6subtract(values)
Left-folds subtraction. Throws TypeError on empty input.
subtract([10, 3, 2]); // 5product(values)
Throws TypeError on empty input.
product([2, 3, 4]); // 24average(values)
Returns NaN on empty input (consistent with 0 / 0).
average([2, 4, 6]); // 4hasEvenLength(values)
hasEvenLength([1, 2]); // truehasEvenLength([1, 2, 3]); // falsemedian(values)
Numeric sort, does not mutate the input. Even-length arrays return the
mean of the two middle values. Throws TypeError on empty input.
median([3, 1, 2]); // 2median([1, 2, 3, 4]); // 2.5median([10, 2, 1]); // 2 (numeric sort, not lexicographic)mode(values)
Returns every value tied for the highest occurrence count, in first-seen
order. Returns [] for empty input.
mode([1, 2, 2, 3]); // [2]mode([1, 1, 2, 2, 3]); // [1, 2]range(values)
Difference between the largest and smallest value (a.k.a. extent or
spread). Single pass. Single-element input returns 0. Any NaN in
the input propagates to the result (matches Math.min / Math.max).
Throws TypeError on empty input.
range([1, 5, 3, 9, 2]); // 8range([42]); // 0variance(values, mode?)
Variance of the values. Two-pass algorithm (mean, then average of squared deviations).
mode = 'population'(default) divides byn(σ²).mode = 'sample'divides byn − 1(s², Bessel’s correction).- Any
NaNin the input propagates to the result (matchesrange).
Throws TypeError on empty input, or on single-element input when
mode === 'sample'.
variance([2, 4, 4, 4, 5, 5, 7, 9]); // 4variance([2, 4, 4, 4, 5, 5, 7, 9], 'sample'); // ≈ 4.5714…variance([5]); // 0 (population)standardDeviation(values, mode?)
Square root of variance(values, mode). Same 'population' /
'sample' modes and same throw conditions. Any NaN in the input
propagates to the result.
standardDeviation([2, 4, 4, 4, 5, 5, 7, 9]); // 2standardDeviation([2, 4, 4, 4, 5, 5, 7, 9], 'sample'); // ≈ 2.1380…quantile(values, q)
Quantile of values using linear interpolation between adjacent
ordered values (the “R-7” / Excel / NumPy-default method, which
generalises median so that quantile(values, 0.5) agrees with
median(values)).
q = 0returns the minimum,q = 1the maximum.- Sorts numerically, does not mutate the input.
- Any
NaNin the input propagates to the result (matchesvarianceandstandardDeviation).
Throws TypeError on empty input. Throws RangeError when
q is outside [0, 1] or is NaN.
quantile([1, 2, 3, 4], 0.5); // 2.5quantile([1, 2, 3, 4], 0.25); // 1.75quantile([1, 2, 3, 4], 0.75); // 3.25quantile([1, 2, 3, 4], 0); // 1quantile([1, 2, 3, 4], 1); // 4cumulativeSum(values)
Running totals: returns an array of the same length where each element
is the sum of all input values up to and including that index. Returns
[] for empty input. Any NaN poisons that position and every
subsequent position.
cumulativeSum([1, 2, 3, 4]); // [1, 3, 6, 10]cumulativeSum([]); // []minBy(collection, key)
Returns the item with the smallest numeric value at key
(dot-delimited for nested paths), or undefined when no item has a
comparable numeric value. Returns the source item, not the resolved
numeric value. Empty input returns undefined. Ties resolve to the
first occurrence. Items where the resolved value is missing, NaN,
or not a number are excluded from comparison.
const products = [{ price: 9 }, { price: 3 }, { price: 7 }];minBy(products, 'price'); // { price: 3 }
const users = [ { name: 'Ana', profile: { age: 30 } }, { name: 'Bob', profile: { age: 22 } },];minBy(users, 'profile.age'); // { name: 'Bob', profile: { age: 22 } }maxBy(collection, key)
Returns the item with the largest numeric value at key
(dot-delimited for nested paths), or undefined when no item has a
comparable numeric value. Returns the source item, not the resolved
numeric value. Empty input returns undefined. Ties resolve to the
first occurrence. Items where the resolved value is missing, NaN,
or not a number are excluded from comparison.
const products = [{ price: 9 }, { price: 3 }, { price: 7 }];maxBy(products, 'price'); // { price: 9 }
const users = [ { name: 'Ana', profile: { age: 30 } }, { name: 'Bob', profile: { age: 22 } },];maxBy(users, 'profile.age'); // { name: 'Ana', profile: { age: 30 } }sumBy(collection, key)
Sum of the numeric values at key (dot-delimited for nested paths)
across every item in collection. Strict: any item where the
resolved value is missing or not a number throws TypeError. Empty
input returns 0 (matches sum). NaN propagates.
sumBy([{ total: 10 }, { total: 5 }], 'total'); // 15
const orders = [ { shipping: { fee: 5 } }, { shipping: { fee: 7.5 } },];sumBy(orders, 'shipping.fee'); // 12.5averageBy(collection, key)
Arithmetic mean of the numeric values at key (dot-delimited for
nested paths) across every item in collection. Strict: any item
where the resolved value is missing or not a number throws
TypeError. Empty input returns NaN (matches average,
consistent with 0 / 0). NaN propagates.
averageBy([{ grade: 80 }, { grade: 90 }], 'grade'); // 85
const users = [ { name: 'Ana', profile: { age: 20 } }, { name: 'Bob', profile: { age: 40 } },];averageBy(users, 'profile.age'); // 30