Skip to content

N (Number)

sum(nums: number[]): number
mean(nums: number[]): Option<number>
median(nums: number[]): Option<number>
variance(nums: number[]): Option<number>
standardDeviation(nums: number[]): Option<number>
min(nums: number[]): Option<number>
max(nums: number[]): Option<number>
minMax(nums: number[]): Option<readonly [number, number]>

Every partial aggregate also has an explicit *OrUndefined variant. Use the *NonEmpty variants when a readonly non-empty tuple proves a result exists, and the sample-statistic *AtLeastTwo variants when two inputs are required.

percentile(p: number): (nums: number[]) => Option<number>
percentileOrUndefined(p: number): (nums: number[]) => number | undefined
percentileNonEmpty(p: number): (nums: readonly [number, ...number[]]) => number
clamp(min: number, max: number): (value: number) => number
dotProduct(b: number[]): (a: number[]) => number
isEven(n: number): boolean
isOdd(n: number): boolean
import { pipe } from '@stopcock/fp'
import * as A from '@stopcock/fp/array'
import * as N from '@stopcock/fp/number'
import * as O from '@stopcock/fp/option'
// stats on response times
const times = [120, 95, 200, 88, 150, 300, 110] as const
pipe(N.mean(times), O.getOrElse(() => 0)) // ~151.9
N.medianNonEmpty(times) // 120
N.standardDeviationNonEmpty(times) // ~68.6
N.percentileNonEmpty(95)(times) // 300
// clamp user input
pipe(userAge, N.clamp(0, 150))
// average score, ignoring zeros
pipe(
scores,
A.filter((s) => s > 0),
N.mean,
)
// feature vector similarity
N.dotProduct([0, 1, 1])([1, 0, 1]) // 1