@devxbhuvn/array-fns
v2.0.1
Published
Modern, dependency-free TypeScript array utilities for everyday JavaScript and TypeScript development.
Maintainers
Readme
@devxbhuvn/array-fns
Modern, immutable, dependency-free TypeScript array utilities — including great helpers for arrays of objects.
@devxbhuvn/array-fns gives you focused functions for searching, transforming, grouping, sorting, sampling, combining, and editing arrays. Every helper accepts readonly inputs, returns a new result, and never mutates the original array.
✨ Features
- 🧊 Immutable by default — inputs are never modified
- 🧠 TypeScript-first — generics, type-guard overloads, and shared types
- 📦 Tree-shakeable — ESM + CJS,
sideEffects: false, deep imports - 🔗 Predictable equality — SameValueZero for set/search helpers (
NaNequalsNaN) - 🗺️ Map + Record APIs — pick the shape that fits your app
- 🎲 Testable randomness — inject
random?: () => numberinto sample/shuffle helpers - 🚫 Zero runtime dependencies
📦 Installation
npm install @devxbhuvn/array-fnsRequirements: Node.js 20+ (or a modern ES2020 browser).
Deep imports
import { unique } from '@devxbhuvn/array-fns/unique';ESM
import { groupBy, orderBy, unique } from '@devxbhuvn/array-fns';CommonJS
const { chunk, range } = require('@devxbhuvn/array-fns');🚀 Quick start
import { groupBy, keyBy, orderBy, pluck, sumBy, unique } from '@devxbhuvn/array-fns';
type User = {
id: number;
name: string;
team: string;
score: number;
};
const users: User[] = [
{ id: 1, name: 'Maya', team: 'platform', score: 12 },
{ id: 2, name: 'Noah', team: 'design', score: 8 },
{ id: 3, name: 'Ava', team: 'platform', score: 15 },
{ id: 1, name: 'Maya', team: 'platform', score: 12 }
];
const deduped = unique(users, (user) => user.id);
const byTeam = groupBy(deduped, (user) => user.team);
const byId = keyBy(deduped, (user) => user.id);
const ranked = orderBy(deduped, [(user) => user.score], ['desc']);
const names = pluck(ranked, 'name');
console.log(byTeam.platform.length); // 2
console.log(byId[2]?.name); // Noah
console.log(ranked[0]?.name); // Ava
console.log(sumBy(deduped, (user) => user.score)); // 35
console.log(names); // ['Ava', 'Maya', 'Noah']📚 Table of contents
- ✨ Features
- 📦 Installation
- 🚀 Quick start
- 🧠 Core concepts
- 🧩 Recipes
- 🔍 Search & test
- 🔄 Transform & reduce
- ✂️ Slice & split
- 🧱 Structure & windows
- 🗂️ Arrays of objects
- 🗺️ Map helpers
- 🔗 Set operations
- 🧮 Aggregates & stats
- ✏️ Immutable edits
- 🎲 Random
- 🛠️ Create
- 🔤 A–Z API index
- ⚠️ Edge cases & errors
- 🔁 Migrating from 1.x
- 📘 TypeScript types
- 📤 Package output
- 📄 License
🧠 Core concepts
Immutability
All helpers return new arrays/values. Nested object references are not deep-cloned.
import { reverse, sortBy } from '@devxbhuvn/array-fns';
const numbers = [3, 1, 2];
sortBy(numbers, (value) => value); // [1, 2, 3]
console.log(numbers); // [3, 1, 2] — unchangedCallback shape
Predicates, selectors, and mappers receive (value, index, array).
import { map } from '@devxbhuvn/array-fns';
map([10, 20, 30], (value, index) => value + index); // [10, 21, 32]Equality (SameValueZero)
Set/search helpers (unique, union, difference, intersection, includes, …) use SameValueZero:
NaN equals NaN, and +0 equals -0. Objects compare by reference unless you pass a selector / comparator.
import { includes, unique } from '@devxbhuvn/array-fns';
includes([1, NaN], NaN); // true
unique([{ id: 1 }, { id: 1 }]); // keeps both (different references)
unique([{ id: 1 }, { id: 1 }], (item) => item.id); // [{ id: 1 }]Records vs Maps
groupBy/keyBy/countBy→ null-prototypeRecord(string/number/symbol keys)groupToMap/indexToMap/frequencies→Map(any key type, SameValueZero)
Optional RNG
sample, sampleSize, shuffle, and sampleWeighted accept an optional final random?: () => number (default Math.random) for deterministic tests.
🧩 Recipes
Deduplicate objects by id
import { unique } from '@devxbhuvn/array-fns';
unique(users, (user) => user.id);Group, index, and rank
import { groupBy, keyBy, orderBy } from '@devxbhuvn/array-fns';
groupBy(users, (user) => user.team);
keyBy(users, (user) => user.id);
orderBy(users, [(user) => user.score], ['desc']);Pull fields / build lookups
import { pluck, zipObject } from '@devxbhuvn/array-fns';
pluck(users, 'name');
zipObject(['a', 'b'], [1, 2]); // { a: 1, b: 2 }Immutable list edits
import { insertAt, replace, splice } from '@devxbhuvn/array-fns';
insertAt(users, 0, newUser);
replace(users, (user) => user.id === 2, { ...users[1], score: 99 });
splice(ids, 1, 2, 9);🔍 Search & test
filter
Returns a filtered copy of the array.
function filter<T, S extends T>(array: readonly T[], predicate: TypeGuardPredicate<T, S>): S[];
function filter<T>(array: readonly T[], predicate: Predicate<T>): T[];
function filter<T>(array: readonly T[], predicate: Predicate<T>): T[];Notes: Supports type-guard predicates for narrowing.
import { filter } from '@devxbhuvn/array-fns';
filter([1, 2, 3, 4], (v) => v % 2 === 0); // [2, 4]find
Returns the first value that matches a predicate.
function find<T, S extends T>(array: readonly T[], predicate: TypeGuardPredicate<T, S>): S | undefined;
function find<T>(array: readonly T[], predicate: Predicate<T>): T | undefined;
function find<T>(array: readonly T[], predicate: Predicate<T>): T | undefined;Notes: Supports type-guard predicates. Missing → undefined.
import { find } from '@devxbhuvn/array-fns';
find([1, 2, 3], (v) => v > 1); // 2findIndex
Returns the index of the first element that matches the predicate.
function findIndex<T>(array: readonly T[], predicate: Predicate<T>, fromIndex = 0): number;Notes: fromIndex clamps like native findIndex. Missing → -1.
import { findIndex } from '@devxbhuvn/array-fns';
findIndex(['a', 'b', 'c'], (v) => v === 'b'); // 1findLast
Returns the last value that matches a predicate.
function findLast<T, S extends T>(array: readonly T[], predicate: TypeGuardPredicate<T, S>): S | undefined;
function findLast<T>(array: readonly T[], predicate: Predicate<T>): T | undefined;
function findLast<T>(array: readonly T[], predicate: Predicate<T>): T | undefined;Notes: Searches from the end. Supports type guards.
import { findLast } from '@devxbhuvn/array-fns';
findLast([1, 2, 3, 4], (v) => v % 2 === 0); // 4findLastIndex
Returns the last index that matches a predicate, or -1.
function findLastIndex<T>(array: readonly T[], predicate: Predicate<T>): number;Notes: Missing → -1.
import { findLastIndex } from '@devxbhuvn/array-fns';
findLastIndex([1, 2, 3, 2], (v) => v === 2); // 3findMap
Maps each item and returns the first defined (non-undefined) result.
function findMap<T, R>(array: readonly T[], mapper: Iteratee<T, R | undefined>): R | undefined;Notes: First non-undefined mapped value wins.
import { findMap } from '@devxbhuvn/array-fns';
findMap([1, 2, 3], (v) => (v > 1 ? v * 10 : undefined)); // 20some
Returns true when at least one value matches a predicate.
function some<T>(array: readonly T[], predicate: Predicate<T>): boolean;Notes: Empty array → false.
import { some } from '@devxbhuvn/array-fns';
some([1, 2, 3], (v) => v === 2); // trueevery
Returns true when every value matches a predicate.
function every<T>(array: readonly T[], predicate: Predicate<T>): boolean;Notes: Empty array → true.
import { every } from '@devxbhuvn/array-fns';
every([2, 4], (v) => v % 2 === 0); // truenone
Returns true when no value matches the predicate.
function none<T>(array: readonly T[], predicate: Predicate<T>): boolean;Notes: True when no item matches.
import { none } from '@devxbhuvn/array-fns';
none([1, 3, 5], (v) => v % 2 === 0); // trueincludes
Returns true when the array contains a value using SameValueZero equality.
function includes<T>(array: readonly T[], search: T, fromIndex = 0): boolean;Notes: SameValueZero (NaN matches NaN).
import { includes } from '@devxbhuvn/array-fns';
includes([1, NaN], NaN); // trueincludesAll
Returns true when every search value is in the array (SameValueZero).
function includesAll<T>(array: readonly T[], values: readonly T[]): boolean;Notes: Every search value must be present.
import { includesAll } from '@devxbhuvn/array-fns';
includesAll([1, 2, 3], [1, 3]); // trueincludesAny
Returns true when any search value is in the array (SameValueZero).
function includesAny<T>(array: readonly T[], values: readonly T[]): boolean;Notes: At least one search value present.
import { includesAny } from '@devxbhuvn/array-fns';
includesAny([1, 2], [4, 2]); // trueindexOf
Returns the first index of a value, or -1 when it is absent.
function indexOf<T>(array: readonly T[], search: T, fromIndex = 0): number;Notes: SameValueZero. Missing → -1.
import { indexOf } from '@devxbhuvn/array-fns';
indexOf(['a', 'b', 'a'], 'a'); // 0lastIndexOf
Returns the last index of a value, or -1 when it is absent.
function lastIndexOf<T>(array: readonly T[], search: T, fromIndex = array.length - 1): number;Notes: Searches from the end. Missing → -1.
import { lastIndexOf } from '@devxbhuvn/array-fns';
lastIndexOf(['a', 'b', 'a'], 'a'); // 2first
Returns the first element of an array, or undefined for an empty array.
function first<T>(array: readonly T[]): T | undefined;Notes: Empty → undefined.
import { first } from '@devxbhuvn/array-fns';
first([10, 20]); // 10last
Returns the last element of an array or undefined if the array is empty.
function last<T>(array: readonly T[]): T | undefined;Notes: Empty → undefined.
import { last } from '@devxbhuvn/array-fns';
last([10, 20]); // 20at
Returns the element at index, supporting negative indexes.
function at<T>(array: readonly T[], index: number): T | undefined;Notes: Supports negative indexes. Out of range → undefined.
import { at } from '@devxbhuvn/array-fns';
at([10, 20, 30], -1); // 30count
Counts the number of items in an array that satisfy a predicate.
function count<T>(array: readonly T[], predicate: Predicate<T> = () => true): number;Notes: Default predicate counts all items (array.length).
import { count } from '@devxbhuvn/array-fns';
count([1, 2, 3, 4], (v) => v % 2 === 0); // 2countWhere
Counts items that satisfy a predicate.
function countWhere<T>(array: readonly T[], predicate: Predicate<T>): number;Notes: Same idea as count with a required predicate.
import { countWhere } from '@devxbhuvn/array-fns';
countWhere([1, 2, 3], (v) => v > 1); // 2startsWith
Returns true when array begins with prefix (SameValueZero).
function startsWith<T>(array: readonly T[], prefix: readonly T[]): boolean;Notes: SameValueZero per prefix element.
import { startsWith } from '@devxbhuvn/array-fns';
startsWith([1, 2, 3], [1, 2]); // trueendsWith
Returns true when array ends with suffix (SameValueZero).
function endsWith<T>(array: readonly T[], suffix: readonly T[]): boolean;Notes: SameValueZero per suffix element.
import { endsWith } from '@devxbhuvn/array-fns';
endsWith([1, 2, 3], [2, 3]); // trueequals
Shallow array equality using SameValueZero per index.
function equals<T>(first: readonly T[], second: readonly T[]): boolean;Notes: Same length + SameValueZero per index (shallow).
import { equals } from '@devxbhuvn/array-fns';
equals([1, NaN], [1, NaN]); // truebinarySearch
Binary search on an ascending sorted array.
function binarySearch<T>(array: readonly T[], value: T): number;Notes: Assumes ascending sorted input. Missing value → -1.
import { binarySearch } from '@devxbhuvn/array-fns';
binarySearch([1, 3, 5, 7], 5); // 2isEmpty
Returns true when the array has no elements.
function isEmpty(array: readonly unknown[]): boolean;Notes: array.length === 0.
import { isEmpty } from '@devxbhuvn/array-fns';
isEmpty([]); // trueisSorted
Returns true when the array is sorted ascending (or by comparator).
function isSorted<T>(array: readonly T[], comparator?: Comparator<T>): boolean;Notes: Checks non-decreasing order by default compare.
import { isSorted } from '@devxbhuvn/array-fns';
isSorted([1, 2, 2, 3]); // trueisSubset
Returns true when every value in subset is in array (SameValueZero).
function isSubset<T>(subset: readonly T[], array: readonly T[]): boolean;Notes: Every value of subset is in array.
import { isSubset } from '@devxbhuvn/array-fns';
isSubset([1, 2], [1, 2, 3]); // trueisSuperset
Returns true when array contains every value in subset (SameValueZero).
function isSuperset<T>(array: readonly T[], subset: readonly T[]): boolean;Notes: array contains every value of subset.
import { isSuperset } from '@devxbhuvn/array-fns';
isSuperset([1, 2, 3], [1, 2]); // true🔄 Transform & reduce
map
Returns a new array containing the mapped values.
function map<T, R>(array: readonly T[], mapper: (value: T, index: number, array: readonly T[]) => R): R[];Notes: Immutable map with (value, index, array).
import { map } from '@devxbhuvn/array-fns';
map([1, 2, 3], (v, i) => v + i); // [1, 3, 5]flatMap
Maps values and flattens one level of returned arrays.
function flatMap<T, R>(array: readonly T[], mapper: (value: T, index: number, array: readonly T[]) => R | readonly R[]): R[];Notes: Flattens one level of returned arrays.
import { flatMap } from '@devxbhuvn/array-fns';
flatMap([1, 2], (v) => [v, v * 10]); // [1,10,2,20]flatMapDeep
Maps each value then fully flattens nested array results.
function flatMapDeep<T, R>(array: readonly T[], mapper: (value: T, index: number, array: readonly T[]) => R | readonly unknown[]): R[];Notes: Map then fully flatten nested arrays.
import { flatMapDeep } from '@devxbhuvn/array-fns';
flatMapDeep([1, 2], (v) => [v, [v * 10]]); // [1,10,2,20]compactMap
Maps values and drops null / undefined results.
function compactMap<T, R>(array: readonly T[], mapper: Iteratee<T, R | null | undefined>): R[];Notes: Map + drop null/undefined in one pass.
import { compactMap } from '@devxbhuvn/array-fns';
compactMap([1, 2, 3], (v) => (v % 2 ? v : null)); // [1, 3]compact
Removes falsy values from an array.
function compact<T>(array: readonly T[]): Array<Exclude<T, Falsy>>;Notes: Removes falsy values (false, 0, '', null, undefined, NaN, 0n).
import { compact } from '@devxbhuvn/array-fns';
compact([0, 1, false, 2, '', 3]); // [1, 2, 3]compactBy
Removes values for which the predicate returns true.
function compactBy<T>(array: readonly T[], predicate: Predicate<T>): T[];Notes: Opposite of filter when predicate means “drop me”.
import { compactBy } from '@devxbhuvn/array-fns';
compactBy([1, null, 2], (v) => v == null); // [1, 2]flatten
Flattens nested arrays to a given depth.
function flatten<T>(array: readonly unknown[], depth = 1): T[];Notes: depth is a non-negative integer or Infinity.
import { flatten } from '@devxbhuvn/array-fns';
flatten([1, [2, [3]]], 1); // [1, 2, [3]]flattenDeep
Fully flattens nested arrays.
function flattenDeep<T>(array: readonly unknown[]): T[];Notes: Same as flatten(array, Infinity).
import { flattenDeep } from '@devxbhuvn/array-fns';
flattenDeep([1, [2, [3]]]); // [1, 2, 3]reverse
Returns a reversed copy without mutating the input.
function reverse<T>(array: readonly T[]): T[];Notes: Does not mutate input.
import { reverse } from '@devxbhuvn/array-fns';
reverse([1, 2, 3]); // [3,2,1]rotate
Rotates values left by N positions without mutating the input.
function rotate<T>(array: readonly T[], positions: number): T[];Notes: Positive = left rotate.
import { rotate } from '@devxbhuvn/array-fns';
rotate([1, 2, 3, 4], 1); // [2,3,4,1]reduce
reduce helper.
function reduce<T, R>(array: readonly T[], reducer: (accumulator: R, value: T, index: number, array: readonly T[]) => R, initialValue: R): R;
function reduce<T>(array: readonly T[], reducer: (accumulator: T, value: T, index: number, array: readonly T[]) => T): T;
function reduce<T, R>(array: readonly T[], reducer: (accumulator: R | T, value: T, index: number, array: readonly T[]) => R | T, initialValue?: R): R | T;Notes: Throws on empty array without initial.
import { reduce } from '@devxbhuvn/array-fns';
reduce([1, 2, 3], (a, v) => a + v, 0); // 6reduceRight
reduceRight helper.
function reduceRight<T, R>(array: readonly T[], reducer: (accumulator: R, value: T, index: number, array: readonly T[]) => R, initialValue: R): R;
function reduceRight<T>(array: readonly T[], reducer: (accumulator: T, value: T, index: number, array: readonly T[]) => T): T;
function reduceRight<T, R>(array: readonly T[], reducer: (accumulator: R | T, value: T, index: number, array: readonly T[]) => R | T, initialValue?: R): R | T;Notes: Right-to-left reduce. Same empty rules as reduce.
import { reduceRight } from '@devxbhuvn/array-fns';
reduceRight(['a', 'b'], (a, v) => a + v, ''); // 'ba'reduceWhile
Reduces while predicate remains true for the current accumulator and value. Stops before applying the reducer when the predicate fails.
function reduceWhile<T, R>(Notes: Stops before reducer when predicate fails.
import { reduceWhile } from '@devxbhuvn/array-fns';
reduceWhile(
[1, 2, 3, 4],
(s, v) => s + v <= 6,
(s, v) => s + v,
0
); // 6scan
Like reduce, but returns the list of intermediate accumulator values.
function scan<T, R>(array: readonly T[], iteratee: (accumulator: R, value: T, index: number, array: readonly T[]) => R, initial: R): R[];Notes: All intermediate accumulators.
import { scan } from '@devxbhuvn/array-fns';
scan([1, 2, 3], (s, v) => s + v, 0); // [1,3,6]reject
Returns values for which the predicate returns false.
function reject<T>(array: readonly T[], predicate: Predicate<T>): T[];Notes: Inverse of filter.
import { reject } from '@devxbhuvn/array-fns';
reject([1, 2, 3, 4], (v) => v % 2 === 0); // [1, 3]tap
Invokes interceptor with a shallow copy for side effects and returns a new shallow copy.
function tap<T>(array: readonly T[], interceptor: (value: T[]) => void): T[];Notes: Side-effect helper; returns a fresh shallow copy.
import { tap } from '@devxbhuvn/array-fns';
tap([1, 2], (copy) => console.log(copy));✂️ Slice & split
take
Returns the first N items from the array.
function take<T>(array: readonly T[], count = 1): T[];Notes: count non-negative integer (default 1).
import { take } from '@devxbhuvn/array-fns';
take([1, 2, 3], 2); // [1, 2]takeRight
Returns up to the last N values without mutating the input.
function takeRight<T>(array: readonly T[], count: number): T[];Notes: Last N values.
import { takeRight } from '@devxbhuvn/array-fns';
takeRight([1, 2, 3, 4], 2); // [3, 4]takeWhile
Returns values from the start while a predicate remains true.
function takeWhile<T, S extends T>(array: readonly T[], predicate: TypeGuardPredicate<T, S>): S[];
function takeWhile<T>(array: readonly T[], predicate: Predicate<T>): T[];
function takeWhile<T>(array: readonly T[], predicate: Predicate<T>): T[];Notes: Supports type-guard predicates.
import { takeWhile } from '@devxbhuvn/array-fns';
takeWhile([1, 1, 2, 3], (v) => v === 1); // [1, 1]takeUntil
Takes values until the predicate returns true (exclusive).
function takeUntil<T>(array: readonly T[], predicate: Predicate<T>): T[];Notes: Stops before the matching element.
import { takeUntil } from '@devxbhuvn/array-fns';
takeUntil([1, 2, 3, 4], (v) => v === 3); // [1, 2]takeLastWhile
Returns values from the end while a predicate remains true.
function takeLastWhile<T>(array: readonly T[], predicate: Predicate<T>): T[];Notes: Takes a trailing run while predicate holds.
import { takeLastWhile } from '@devxbhuvn/array-fns';
takeLastWhile([1, 2, 3, 4], (v) => v > 2); // [3,4]drop
Returns an array without the first N elements.
function drop<T>(array: readonly T[], count = 1): T[];Notes: count must be a non-negative integer (default 1).
import { drop } from '@devxbhuvn/array-fns';
drop([1, 2, 3], 2); // [3]dropRight
Returns the input without its last N values.
function dropRight<T>(array: readonly T[], count: number): T[];Notes: Fractional counts truncate toward zero; negatives act like 0.
import { dropRight } from '@devxbhuvn/array-fns';
dropRight([1, 2, 3], 1); // [1, 2]dropWhile
Returns values after the initial values that match a predicate.
function dropWhile<T>(array: readonly T[], predicate: Predicate<T>): T[];Notes: Drops a leading run while predicate is true.
import { dropWhile } from '@devxbhuvn/array-fns';
dropWhile([1, 1, 2, 3], (v) => v === 1); // [2, 3]dropUntil
Drops values until the predicate returns true, then returns the remainder including the match.
function dropUntil<T>(array: readonly T[], predicate: Predicate<T>): T[];Notes: Keeps from the first match onward (inclusive).
import { dropUntil } from '@devxbhuvn/array-fns';
dropUntil([1, 2, 3, 4], (v) => v === 3); // [3, 4]dropLastWhile
Drops trailing values while a predicate remains true.
function dropLastWhile<T>(array: readonly T[], predicate: Predicate<T>): T[];Notes: Drops from the end while predicate holds.
import { dropLastWhile } from '@devxbhuvn/array-fns';
dropLastWhile([1, 2, 3, 4], (v) => v > 2); // [1, 2]initial
Returns all elements except the last.
function initial<T>(array: readonly T[]): T[];Notes: Empty / single-element → [].
import { initial } from '@devxbhuvn/array-fns';
initial([1, 2, 3]); // [1, 2]tail
Returns all elements except the first.
function tail<T>(array: readonly T[]): T[];Notes: Empty → [].
import { tail } from '@devxbhuvn/array-fns';
tail([1, 2, 3]); // [2, 3]splitAt
Splits the array into [left, right] at index.
function splitAt<T>(array: readonly T[], index: number): [T[], T[]];Notes: Index clamped for insert-style splits.
import { splitAt } from '@devxbhuvn/array-fns';
splitAt([1, 2, 3, 4], 2); // [[1,2],[3,4]]splitWhen
Splits at the first index where the predicate is true.
function splitWhen<T>(array: readonly T[], predicate: Predicate<T>): [T[], T[]];Notes: Split before first matching index.
import { splitWhen } from '@devxbhuvn/array-fns';
splitWhen([1, 2, 3, 4], (v) => v === 3); // [[1,2],[3,4]]span
Returns [prefix, rest] where prefix is the longest takeWhile run.
function span<T>(array: readonly T[], predicate: Predicate<T>): [T[], T[]];Notes: [takeWhile(...), dropWhile(...)].
import { span } from '@devxbhuvn/array-fns';
span([1, 1, 2, 3], (v) => v === 1); // [[1,1],[2,3]]partition
Splits an array into two arrays based on a predicate.
function partition<T>(array: readonly T[], predicate: Predicate<T>): [T[], T[]];Notes: Splits into [pass, fail] by predicate.
import { partition } from '@devxbhuvn/array-fns';
partition([1, 2, 3, 4], (v) => v % 2 === 0); // [[2,4],[1,3]]🧱 Structure & windows
chunk
Splits an array into chunks of the provided size.
function chunk<T>(array: readonly T[], size: number): T[][];Notes: size must be a positive integer.
import { chunk } from '@devxbhuvn/array-fns';
chunk([1, 2, 3, 4, 5], 2); // [[1,2],[3,4],[5]]chunkBy
Splits into runs of consecutive equal selector keys.
function chunkBy<T, K extends PropertyKey>(array: readonly T[], selector: Selector<T, K>): T[][];Notes: Groups consecutive equal keys only (not global groupBy).
import { chunkBy } from '@devxbhuvn/array-fns';
chunkBy([1, 1, 2, 2, 1], (v) => v); // [[1,1],[2,2],[1]]sliding
Returns overlapping windows of size advancing by step. Partial trailing windows are omitted.
function sliding<T>(array: readonly T[], size: number, step = 1): T[][];Notes: Omits trailing partial windows.
import { sliding } from '@devxbhuvn/array-fns';
sliding([1, 2, 3, 4], 2); // [[1,2],[2,3],[3,4]]partitionBy
Splits into consecutive runs keyed by the selector. Returns [key, items] tuples (different shape from chunkBy).
function partitionBy<T, K>(array: readonly T[], selector: Iteratee<T, K>): Array<[K, T[]]>;Notes: Consecutive runs as [key, items][] (unlike chunkBy).
import { partitionBy } from '@devxbhuvn/array-fns';
partitionBy([1, 1, 2, 2], (v) => v); // [[1,[1,1]],[2,[2,2]]]intersperse
Inserts separator between adjacent elements.
function intersperse<T>(array: readonly T[], separator: T): T[];Notes: Inserts separator between elements.
import { intersperse } from '@devxbhuvn/array-fns';
intersperse([1, 2, 3], 0); // [1, 0, 2, 0, 3]interleave
Weaves values from multiple arrays by index until the longest is exhausted.
function interleave(): [];
function interleave<T1>(a: readonly T1[]): T1[];
function interleave<T1, T2>(a: readonly T1[], b: readonly T2[]): Array<T1 | T2>;
function interleave<T1, T2, T3>(a: readonly T1[], b: readonly T2[], c: readonly T3[]): Array<T1 | T2 | T3>;
function interleave<T1, T2, T3, T4>(a: readonly T1[], b: readonly T2[], c: readonly T3[], d: readonly T4[]): Array<T1 | T2 | T3 | T4>;Notes: Round-robins by index across inputs.
import { interleave } from '@devxbhuvn/array-fns';
interleave([1, 2], ['a', 'b', 'c']); // [1,'a',2,'b','c']transpose
Transposes a matrix (rows to columns). Ragged rows are truncated to the shortest row.
function transpose<T>(matrix: ReadonlyArray<readonly T[]>): T[][];Notes: Ragged rows truncated to shortest length.
import { transpose } from '@devxbhuvn/array-fns';
transpose([
[1, 2, 3],
[4, 5, 6]
]); // [[1,4],[2,5],[3,6]]zip
Combines two arrays into a list of tuples.
function zip<A, B>(first: readonly A[], second: readonly B[]): Array<[A, B]>;Notes: Stops at shortest length.
import { zip } from '@devxbhuvn/array-fns';
zip([1, 2], ['a', 'b', 'c']); // [[1,'a'],[2,'b']]zipWith
Combines two arrays with a mapper function.
function zipWith<A, B, R>(first: readonly A[], second: readonly B[], mapper: (left: A, right: B) => R): R[];Notes: Zip + map in one step.
import { zipWith } from '@devxbhuvn/array-fns';
zipWith([1, 2], [10, 20], (a, b) => a + b); // [11, 21]zipLongest
Zips arrays to the longest length, padding missing values with undefined.
function zipLongest<A, B>(first: readonly A[], second: readonly B[]): Array<[A | undefined, B | undefined]>;Notes: Pads missing side with undefined.
import { zipLongest } from '@devxbhuvn/array-fns';
zipLongest([1], ['a', 'b']); // [[1,'a'],[undefined,'b']]zipMany
Zips any number of arrays to the shortest length.
function zipMany(): [];
function zipMany<T1>(a: readonly T1[]): [T1][];
function zipMany<T1, T2>(a: readonly T1[], b: readonly T2[]): [T1, T2][];
function zipMany<T1, T2, T3>(a: readonly T1[], b: readonly T2[], c: readonly T3[]): [T1, T2, T3][];
function zipMany<T1, T2, T3, T4>(a: readonly T1[], b: readonly T2[], c: readonly T3[], d: readonly T4[]): [T1, T2, T3, T4][];Notes: N-ary zip to shortest length; tuple overloads.
import { zipMany } from '@devxbhuvn/array-fns';
zipMany([1, 2], ['a', 'b'], [true, false]);zipObject
Creates an object from parallel key and value arrays.
function zipObject<K extends PropertyKey, V>(keys: readonly K[], values: readonly V[]): Record<K, V>;Notes: Parallel keys/values → object.
import { zipObject } from '@devxbhuvn/array-fns';
zipObject(['a', 'b'], [1, 2]); // { a: 1, b: 2 }unzip
Converts an array of coordinate pairs into two arrays.
function unzip<T, U>(entries: readonly (readonly [T, U])[]): [T[], U[]];Notes: Pairs → two arrays.
import { unzip } from '@devxbhuvn/array-fns';
unzip([
[1, 'a'],
[2, 'b']
]); // [[1,2],['a','b']]unzipWith
Combines each column of tuples with an iteratee.
function unzipWith<T, R>(array: ReadonlyArray<readonly T[]>, iteratee: (...values: T[]) => R): R[];Notes: Combine columns with an iteratee.
import { unzipWith } from '@devxbhuvn/array-fns';
unzipWith(
[
[1, 2],
[3, 4]
],
(a, b) => a + b
); // [4, 6]cartesian
Returns the cartesian product of the provided arrays.
function cartesian(): [[]];
function cartesian<T1>(a: readonly T1[]): [T1][];
function cartesian<T1, T2>(a: readonly T1[], b: readonly T2[]): [T1, T2][];
function cartesian<T1, T2, T3>(a: readonly T1[], b: readonly T2[], c: readonly T3[]): [T1, T2, T3][];
function cartesian<T1, T2, T3, T4>(a: readonly T1[], b: readonly T2[], c: readonly T3[], d: readonly T4[]): [T1, T2, T3, T4][];Notes: Empty call returns [[]] (one empty tuple).
import { cartesian } from '@devxbhuvn/array-fns';
cartesian([1, 2], ['a']); // [[1,'a'],[2,'a']]🗂️ Arrays of objects
pluck
Maps each item to the value at key.
function pluck<T extends object, K extends keyof T>(array: readonly T[], key: K): Array<T[K]>;Notes: Pull one property from each object.
import { pluck } from '@devxbhuvn/array-fns';
pluck([{ name: 'Maya' }, { name: 'Noah' }], 'name'); // ['Maya','Noah']keyBy
Creates an object keyed by the selector result, keeping the last value for each key.
function keyBy<T, K extends PropertyKey>(array: readonly T[], selector: Selector<T, K>): Record<K, T>;Notes: Last item wins. Null-prototype object.
import { keyBy } from '@devxbhuvn/array-fns';
keyBy([{ id: 'a' }, { id: 'b' }], (x) => x.id);groupBy
Groups items by a selector result.
function groupBy<T, K extends PropertyKey>(array: readonly T[], selector: Selector<T, K>): Record<K, T[]>;Notes: Null-prototype Record. Safe for __proto__ keys.
import { groupBy } from '@devxbhuvn/array-fns';
groupBy([{ t: 'a' }, { t: 'b' }], (x) => x.t);countBy
Counts values grouped by the result of a selector.
function countBy<T, K extends PropertyKey>(array: readonly T[], selector: Selector<T, K>): Record<K, number>;Notes: Returns a null-prototype Record of counts.
import { countBy } from '@devxbhuvn/array-fns';
countBy(['a', 'a', 'b'], (v) => v); // { a: 2, b: 1 }orderBy
Stable multi-criteria sort with optional per-selector directions.
function orderBy<T>(array: readonly T[], selectors: readonly SortSelector<T>[], orders: readonly OrderDirection[] = []): T[];Notes: Stable multi-key sort with 'asc' | 'desc' per selector.
import { orderBy } from '@devxbhuvn/array-fns';
orderBy(users, [(u) => u.score], ['desc']);sortBy
Returns a stable sorted copy using one or more value selectors.
function sortBy<T>(array: readonly T[], ...selectors: SortSelector<T>[]): T[];Notes: Stable. Multiple selectors = tie-breakers.
import { sortBy } from '@devxbhuvn/array-fns';
sortBy(
tasks,
(t) => t.priority,
(t) => t.title
);sortWith
Returns a sorted copy using one or more explicit comparators.
function sortWith<T>(array: readonly T[], ...comparators: Comparator<T>[]): T[];sortedIndex
Returns the lowest index at which value should be inserted to maintain ascending order. Assumes array is already sorted ascending by SameValueZero-compatible < ordering for primitives.
function sortedIndex<T>(array: readonly T[], value: T): number;Notes: Assumes ascending sorted array.
import { sortedIndex } from '@devxbhuvn/array-fns';
sortedIndex([1, 3, 5], 4); // 2sortedUnique
Removes consecutive duplicates from an ascending-sorted array (SameValueZero).
function sortedUnique<T>(array: readonly T[]): T[];Notes: Only removes consecutive duplicates.
import { sortedUnique } from '@devxbhuvn/array-fns';
sortedUnique([1, 1, 2, 2, 3]); // [1,2,3]Notes: Stable multi-comparator sort.
import { sortWith } from '@devxbhuvn/array-fns';
sortWith([3, 1, 2], (a, b) => a - b); // [1,2,3]maxBy
Returns the item with the largest numeric iteratee result.
function maxBy<T>(array: readonly T[], iteratee: Iteratee<T, number>): T | undefined;Notes: Returns the item with the max iteratee value.
import { maxBy } from '@devxbhuvn/array-fns';
maxBy([{ n: 1 }, { n: 9 }], (x) => x.n); // {n:9}minBy
Returns the item with the smallest numeric iteratee result.
function minBy<T>(array: readonly T[], iteratee: Iteratee<T, number>): T | undefined;Notes: Returns the item with the min iteratee value.
import { minBy } from '@devxbhuvn/array-fns';
minBy([{ n: 1 }, { n: 9 }], (x) => x.n); // {n:1}sumBy
Returns the sum of finite iteratee results.
function sumBy<T>(array: readonly T[], iteratee: Iteratee<T, number>): number;Notes: Sums finite iteratee results.
import { sumBy } from '@devxbhuvn/array-fns';
sumBy([{ n: 2 }, { n: 3 }], (x) => x.n); // 5meanBy
Returns the mean of finite iteratee results, or undefined when none.
function meanBy<T>(array: readonly T[], iteratee: Iteratee<T, number>): number | undefined;Notes: Mean of finite iteratee results.
import { meanBy } from '@devxbhuvn/array-fns';
meanBy([{ n: 2 }, { n: 4 }], (x) => x.n); // 3🗺️ Map helpers
groupToMap
Groups items into a Map keyed by the selector result.
function groupToMap<T, K>(array: readonly T[], selector: Iteratee<T, K>): Map<K, T[]>;Notes: Map twin of groupBy (any key type).
import { groupToMap } from '@devxbhuvn/array-fns';
groupToMap([{ t: 'a' }, { t: 'a' }], (x) => x.t).get('a');indexToMap
Creates a Map keyed by the selector result, keeping the last value for each key.
function indexToMap<T, K>(array: readonly T[], selector: Iteratee<T, K>): Map<K, T>;Notes: Last item wins per key.
import { indexToMap } from '@devxbhuvn/array-fns';
indexToMap([{ id: 1 }, { id: 1, name: 'b' }], (x) => x.id).get(1);frequencies
Counts occurrences of each key (or value when no selector is given). Uses Map SameValueZero semantics.
function frequencies<T>(array: readonly T[]): Map<T, number>;
function frequencies<T, K>(array: readonly T[], selector: Iteratee<T, K>): Map<K, number>;
function frequencies<T, K>(array: readonly T[], selector?: Iteratee<T, K>): Map<T | K, number>;Notes: Returns a Map (SameValueZero keys).
import { frequencies } from '@devxbhuvn/array-fns';
frequencies([1, 1, 2]); // Map { 1 => 2, 2 => 1 }🔗 Set operations
unique
Removes duplicates from an array using SameValueZero semantics.
function unique<T>(array: readonly T[]): T[];
function unique<T, K extends PropertyKey>(array: readonly T[], selector: (value: T, index: number, array: readonly T[]) => K): T[];
function unique<T, K extends PropertyKey>(array: readonly T[], selector?: (value: T, index: number, array: readonly T[]) => K): T[];Notes: Optional selector for object keys.
import { unique } from '@devxbhuvn/array-fns';
unique([1, 1, 2]); // [1,2]
unique(users, (u) => u.id);uniqueWith
Removes duplicates using a custom equality comparator.
function uniqueWith<T>(array: readonly T[], comparator: EqualityComparator<T>): T[];Notes: Custom equality; first occurrence kept.
import { uniqueWith } from '@devxbhuvn/array-fns';
uniqueWith([{ id: 1 }, { id: 1 }], (a, b) => a.id === b.id);union
Returns unique values from multiple arrays in order of appearance.
function union<T>(...arrays: ReadonlyArray<readonly T[]>): T[];Notes: Unique values, first-seen order.
import { union } from '@devxbhuvn/array-fns';
union([1, 2], [2, 3]); // [1, 2, 3]unionBy
Merges arrays keeping the first item for each selector key.
function unionBy<T, K extends PropertyKey>(selector: Selector<T, K>, ...arrays: ReadonlyArray<readonly T[]>): T[];Notes: Selector first, then arrays.
import { unionBy } from '@devxbhuvn/array-fns';
unionBy((x) => x.id, [{ id: 1 }], [{ id: 1 }, { id: 2 }]);unionWith
Merges arrays using a custom equality comparator.
function unionWith<T>(comparator: EqualityComparator<T>, ...arrays: ReadonlyArray<readonly T[]>): T[];Notes: Comparator first, then arrays.
import { unionWith } from '@devxbhuvn/array-fns';
unionWith((a, b) => a.id === b.id, [{ id: 1 }], [{ id: 1 }]);difference
Returns the values in the first array that are not in the other arrays. Equality is based on JavaScript SameValueZero semantics.
function difference<T>(array: readonly T[], other: readonly T[]): T[];Notes: SameValueZero. Order follows the first array.
import { difference } from '@devxbhuvn/array-fns';
difference([1, 2, 3], [2, 4]); // [1, 3]differenceAll
Returns values from the first array that are not present in any of the other arrays (SameValueZero).
function differenceAll<T>(array: readonly T[], ...others: readonly (readonly T[])[]): T[];Notes: Excludes values present in any other array.
import { differenceAll } from '@devxbhuvn/array-fns';
differenceAll([1, 2, 3, 4], [2], [4]); // [1, 3]differenceBy
Returns values from array whose selector keys are not in other.
function differenceBy<T, K extends PropertyKey>(array: readonly T[], other: readonly T[], selector: Selector<T, K>): T[];Notes: Compares selector keys with SameValueZero.
import { differenceBy } from '@devxbhuvn/array-fns';
differenceBy([{ id: 1 }, { id: 2 }], [{ id: 2 }], (x) => x.id); // [{id:1}]differenceWith
Returns values from array not matching any value in other under comparator.
function differenceWith<T>(array: readonly T[], other: readonly T[], comparator: EqualityComparator<T>): T[];Notes: comparator(a,b) === true means equal.
import { differenceWith } from '@devxbhuvn/array-fns';
differenceWith([{ id: 1 }], [{ id: 1 }], (a, b) => a.id === b.id); // []intersection
Returns values that are present in both arrays. Equality is based on JavaScript SameValueZero semantics.
function intersection<T>(first: readonly T[], second: readonly T[]): T[];Notes: Order follows the first array.
import { intersection } from '@devxbhuvn/array-fns';
intersection([1, 2, 3], [2, 3, 4]); // [2, 3]intersectionAll
Returns values present in every input array (SameValueZero), preserving order from the first array.
function intersectionAll<T>(...arrays: readonly (readonly T[])[]): T[];Notes: Intersection across N arrays.
import { intersectionAll } from '@devxbhuvn/array-fns';
intersectionAll([1, 2, 3], [2, 3], [2, 9]); // [2]intersectionBy
Returns unique values from first whose selector keys appear in second.
function intersectionBy<T, K extends PropertyKey>(first: readonly T[], second: readonly T[], selector: Selector<T, K>): T[];Notes: Keeps items from the first array.
import { intersectionBy } from '@devxbhuvn/array-fns';
intersectionBy([{ id: 1 }, { id: 2 }], [{ id: 2 }], (x) => x.id);intersectionWith
Returns unique values from first that match something in second under comparator.
function intersectionWith<T>(first: readonly T[], second: readonly T[], comparator: EqualityComparator<T>): T[];Notes: Custom equality comparator.
import { intersectionWith } from '@devxbhuvn/array-fns';
intersectionWith([{ id: 1 }], [{ id: 1 }], (a, b) => a.id === b.id);xor
Returns values in either array but not both (SameValueZero), preserving order.
function xor<T>(first: readonly T[], second: readonly T[]): T[];Notes: Symmetric difference.
import { xor } from '@devxbhuvn/array-fns';
xor([1, 2, 3], [2, 4]); // [1,3,4]xorBy
Symmetric difference by selector key, preserving first-seen items.
function xorBy<T, K extends PropertyKey>(first: readonly T[], second: readonly T[], selector: Selector<T, K>): T[];Notes: Symmetric difference by selector key.
import { xorBy } from '@devxbhuvn/array-fns';
xorBy([{ id: 1 }, { id: 2 }], [{ id: 2 }, { id: 3 }], (x) => x.id);without
Returns a copy of array without the provided values (SameValueZero).
function without<T>(array: readonly T[], ...values: readonly T[]): T[];Notes: Removes all listed values (SameValueZero).
import { without } from '@devxbhuvn/array-fns';
without([1, 2, 3, 1], 1, 3); // [2]🧮 Aggregates & stats
sum
Returns the sum of finite numbers. Empty arrays return 0.
function sum(array: readonly number[]): number;Notes: Non-finite values ignored. Empty → 0.
import { sum } from '@devxbhuvn/array-fns';
sum([1, 2, 3]); // 6product
Returns the product of finite numbers. Empty arrays return 1.
function product(array: readonly number[]): number;Notes: Product of finite numbers. Empty → 1.
import { product } from '@devxbhuvn/array-fns';
product([2, 3, 4]); // 24mean
Returns the arithmetic mean of finite numbers, or undefined when none.
function mean(array: readonly number[]): number | undefined;Notes: Arithmetic mean of finite numbers. Empty → undefined.
import { mean } from '@devxbhuvn/array-fns';
mean([2, 4, 6]); // 4median
Returns the median of finite numbers, or undefined when none.
function median(array: readonly number[]): number | undefined;Notes: Linear middle of sorted finite values.
import { median } from '@devxbhuvn/array-fns';
median([1, 2, 3, 4]); // 2.5mode
Returns the most frequent value (first on ties), or undefined when empty.
function mode<T>(array: readonly T[]): T | undefined;Notes: Most frequent value (first on ties). Empty → undefined.
import { mode } from '@devxbhuvn/array-fns';
mode([1, 2, 2, 3]); // 2percentile
Returns the percentile of finite numbers using linear interpolation.
function percentile(array: readonly number[], percentileValue: number): number | undefined;Notes: p in [0, 100]; linear interpolation.
import { percentile } from '@devxbhuvn/array-fns';
percentile([0, 10, 20, 30], 50); // 15extent
Returns [min, max] over finite numbers, or undefined when none.
function extent(array: readonly number[]): [number, number] | undefined;Notes: Ignores non-finite numbers. Empty → undefined.
import { extent } from '@devxbhuvn/array-fns';
extent([3, 1, 4]); // [1, 4]variance
Population variance of finite numbers, or undefined when none.
function variance(array: readonly number[]): number | undefined;Notes: Population variance. Empty → undefined.
import { variance } from '@devxbhuvn/array-fns';
variance([2, 4, 4, 4, 5, 5, 7, 9]); // 4stdDev
Population standard deviation of finite numbers, or undefined when none.
function stdDev(array: readonly number[]): number | undefined;Notes: Population stddev (sqrt(variance)). Empty → undefined.
import { stdDev } from '@devxbhuvn/array-fns';
stdDev([2, 4, 4, 4, 5, 5, 7, 9]); // 2max
Returns the maximum finite number, or undefined when empty / no finite values.
function max(array: readonly number[]): number | undefined;Notes: Finite numbers only. Empty → undefined.
import { max } from '@devxbhuvn/array-fns';
max([1, 5, 3]); // 5min
Returns the minimum finite number, or undefined when empty / no finite values.
function min(array: readonly number[]): number | undefined;Notes: Finite numbers only. Empty → undefined.
import { min } from '@devxbhuvn/array-fns';
min([1, 5, 3]); // 1✏️ Immutable edits
insertAt
Returns a copy with values inserted at index.
function insertAt<T>(array: readonly T[], index: number, ...values: readonly T[]): T[];Notes: Negative indexes supported via clamp.
import { insertAt } from '@devxbhuvn/array-fns';
insertAt([1, 3], 1, 2); // [1, 2, 3]removeAt
Returns a copy with the element at index removed. Negative indexes are supported.
function removeAt<T>(array: readonly T[], index: number): T[];Notes: Negative indexes supported. Out of range → copy.
import { removeAt } from '@devxbhuvn/array-fns';
removeAt([1, 2, 3], 1); // [1, 3]updateAt
Returns a copy with the element at index replaced by updater(value).
function updateAt<T>(array: readonly T[], index: number, updater: (value: T) => T): T[];Notes: Updater receives current value.
import { updateAt } from '@devxbhuvn/array-fns';
updateAt([1, 2, 3], 1, (v) => v * 10); // [1,20,3]setAt
Returns a copy with the element at index replaced by value.
function setAt<T>(array: readonly T[], index: number, value: T): T[];Notes: Out-of-range index → unchanged copy.
import { setAt } from '@devxbhuvn/array-fns';
setAt([1, 2, 3], 1, 9); // [1,9,3]move
Moves the item at from to to (immutable).
function move<T>(array: readonly T[], from: number, to: number): T[];Notes: Moves item from from to to (immutable).
import { move } from '@devxbhuvn/array-fns';
move([1, 2, 3, 4], 1, 3); // [1, 3, 4, 2]swap
Swaps values at two indexes (immutable).
function swap<T>(array: readonly T[], firstIndex: number, secondIndex: number): T[];Notes: Out-of-range → unchanged copy.
import { swap } from '@devxbhuvn/array-fns';
swap([1, 2, 3], 0, 2); // [3,2,1]fill
Returns a copy with value filled from start (inclusive) to end (exclusive).
function fill<T>(array: readonly T[], value: T, start = 0, end = array.length): T[];Notes: Immutable fill in [start, end).
import { fill } from '@devxbhuvn/array-fns';
fill([1, 2, 3, 4], 0, 1, 3); // [1, 0, 0, 4]splice
Immutable splice: returns a copy with deleteCount items removed at start and items inserted.
function splice<T>(array: readonly T[], start: number, deleteCount: number, ...items: readonly T[]): T[];Notes: Immutable splice (copy + edit).
import { splice } from '@devxbhuvn/array-fns';
splice([1, 2, 3, 4], 1, 2, 9); // [1,9,4]replace
Returns a copy with the first matching item replaced by replacement (value or updater). If nothing matches, returns a shallow copy.
function replace<T>(array: readonly T[], predicate: Predicate<T>, replacement: T | ((value: T, index: number, array: readonly T[]) => T)): T[];Notes: Replaces first match; value or updater function.
import { replace } from '@devxbhuvn/array-fns';
replace([1, 2, 3, 2], (v) => v === 2, 9); // [1,9,3,2]clampIndex
Clamps an index into [0, length] for insert-style operations. Negative indexes count from the end.
function clampIndex(index: number, length: number): number;Notes: Negative indexes count from the end. length must be ≥ 0.
import { clampIndex } from '@devxbhuvn/array-fns';
clampIndex(-1, 5); // 4🎲 Random
sample
Returns a random element from an array.
function sample<T>(array: readonly T[], random: RandomSource = Math.random): T | undefined;Notes: Optional random?: () => number. Empty → undefined.
import { sample } from '@devxbhuvn/array-fns';
sample([10, 20, 30], () => 0); // 10sampleSize
Returns a random sample of size n from the array.
function sampleSize<T>(array: readonly T[], size: number, random: RandomSource = Math.random): T[];Notes: Partial Fisher–Yates. size ≥ 0 integer.
import { sampleSize } from '@devxbhuvn/array-fns';
sampleSize([1, 2, 3, 4], 2);sampleWeighted
Returns a random item using non-negative weights aligned with array.
function sampleWeighted<T>(array: readonly T[], weights: readonly number[], random: RandomSource = Math.random): T | undefined;Notes: Weights must match length; total > 0.
import { sampleWeighted } from '@devxbhuvn/array-fns';
sampleWeighted(['a', 'b'], [1, 3]);shuffle
Returns a shuffled copy of the array using the Fisher-Yates algorithm.
function shuffle<T>(array: readonly T[], random: RandomSource = Math.random): T[];Notes: Fisher–Yates. Optional RNG.
import { shuffle } from '@devxbhuvn/array-fns';
shuffle([1, 2, 3], () => 0);🛠️ Create
range
Creates a numeric range.
function range(startOrEnd: number, end?: number, step?: number): number[];Notes: range(5) → [0..4]. Step defaults by direction.
import { range } from '@devxbhuvn/array-fns';
range(1, 5); // [1, 2, 3, 4]
range(5, 0, -2); // [5, 3, 1]rangeRight
Creates a numeric range and returns it in reverse order. Argument rules match range.
function rangeRight(startOrEnd: number, end?: number, step?: number): number[];Notes: Same args as range, reversed result.
import { rangeRight } from '@devxbhuvn/array-fns';
rangeRight(5); // [4, 3, 2, 1, 0]times
Creates an array of length count by invoking iteratee with each index.
function times<T>(count: number, iteratee: (index: number) => T): T[];Notes: count must be a non-negative integer.
import { times } from '@devxbhuvn/array-fns';
times(3, (i) => i * 2); // [0, 2, 4]repeat
Creates an array filled with value repeated count times.
function repeat<T>(value: T, count: number): T[];Notes: count must be a non-negative integer.
import { repeat } from '@devxbhuvn/array-fns';
repeat('x', 3); // ['x','x','x']castArray
Wraps a non-array value in an array; returns array values unchanged (shallow copy).
function castArray<T>(value: T | readonly T[]): T[];Notes: Non-arrays are wrapped; arrays are shallow-copied.
import { castArray } from '@devxbhuvn/array-fns';
castArray(1); // [1]
castArray([1, 2]); // [1, 2]🔤 A–Z API index
| Function | Section |
| --------------------------------------- | ------------------- |
| at | Search & test |
| binarySearch | Search & test |
| cartesian | Structure & windows |
| castArray | Create |
| chunk | Structure & windows |
| chunkBy | Structure & windows |
| clampIndex | Immutable edits |
| compact | Transform & reduce |
| compactBy | Transform & reduce |
| compactMap | Transform & reduce |
| count | Search & test |
| countBy | Arrays of objects |
| countWhere | Search & test |
| difference | Set operations |
| differenceAll | Set operations |
| differenceBy | Set operations |
| differenceWith | Set operations |
| drop | Slice & split |
| dropLastWhile | Slice & split |
| dropRight | Slice & split |
| dropUntil | Slice & split |
| dropWhile | Slice & split |
| endsWith | Search & test |
| equals | Search & test |
| every | Search & test |
| extent | Aggregates & stats |
| fill | Immutable edits |
| filter | Search & test |
| find | Search & test |
| findIndex | Search & test |
| findLast | Search & test |
| findLastIndex | Search & test |
| findMap | Search & test |
| first | Search & test |
| flatMap | Transform & reduce |
| flatMapDeep | Transform & reduce |
| flatten | Transform & reduce |
| flattenDeep | Transform & reduce |
| frequencies | Map helpers |
| groupBy | Arrays of objects |
| groupToMap | Map helpers |
| includes | Search & test |
| includesAll | Search & test |
| includesAny | Search & test |
| indexOf | Search & test |
| indexToMap | Map helpers |
| initial | Slice & split |
| insertAt | Immutable edits |
| interleave | Structure & windows |
| intersection | Set operations |
| intersectionAll | Set operations |
| intersectionBy | Set operations |
| intersectionWith | Set operations |
| intersperse | Structure & windows |
| isEmpty | Search & test |
| isSorted | Search & test |
| isSubset | Search & test |
| isSuperset | Search & test |
| keyBy | Arrays of objects |
| last | Search & test |
| lastIndexOf | Search & test |
| map | Transform & reduce |
| max | Aggregates & stats |
| maxBy | Arrays of objects |
| mean | Aggregates & stats |
| meanBy | Arrays of objects |
| median | Aggregates & stats |
| min | Aggregates & stats |
| minBy | Arrays of objects |
| mode | Aggregates & stats |
| move | Immutable edits |
| none | Search & test |
| orderBy | Arrays of objects |
| partition | Slice & split |
| partitionBy | Structure & windows |
| percentile | Aggregates & stats |
| pluck | Arrays of objects |
| product | Aggregates & stats |
| range | Create |
| rangeRight | Create |
| reduce | Transform & reduce |
| reduceRight | Transform & reduce |
| reduceWhile | Transform & reduce |
| reject | Transform & reduce |
| removeAt | Immutable edits |
| repeat | Create |
| replace | Immutable edits |
| reverse | Transform & reduce |
| rotate | Transform & reduce |
| sample | Random |
| sampleSize | Random |
| sampleWeighted | Random |
| scan | Transform & reduce |
| setAt | Immutable edits |
| shuffle | Random |
| sliding | Structure & windows |
| some | Search & test |
| sortBy | Arrays of objects |
| sortWith | Arrays of objects |
| sortedIndex | Other |
| sortedUnique | Other |
| span | Slice & split |
| splice | Immutable edits |
| splitAt | Slice & split |
| splitWhen | Slice & split |
| startsWith | Search & test |
| stdDev | Aggregates & stats |
| sum | Aggregates & stats |
| sumBy | Arrays of objects |
| swap | Immutable edits |
| tail | Slice & split |
| take | Slice & split |
| takeLastWhile | Slice & split |
| takeRight | Slice & split |
| takeUntil | Slice & split |
| takeWhile | Slice & split |
| tap | Transform & reduce |
| times | Create |
| transpose | Structure & windows |
| union | Set operations |
| unionBy | Set operations |
| unionWith | Set operations |
| unique | Set operations |
| uniqueWith | Set operations |
| unzip | Structure & windows |
| unzipWith | Structure & windows |
| updateAt | Immutable edits |
| variance | Aggregates & stats |
| without | Set operations |
| xor | Set operations |
| xorBy | Set operations |
| zip | Structure & windows |
| zipLongest | Structure & windows |
| zipMany | Structure & windows |
| zipObject | Structure & windows |
| zipWith | Structure & windows |
⚠️ Edge cases & errors
chunk,sliding, and related size/step args require positive integersflattendepth must be a non-negative integer orInfinityrange/rangeRightreject invalid bounds; step must be non-zero finitesampleSize,repeat,timesrequire non-negative integer countspercentilerequires a finite value in[0, 100]sampleWeightedrequires matching lengths, non-negative finite weights, total > 0take/droprequire non-negative integer countsreduce/reduceRightthrow on an empty array without an initial value- Empty-safe returns
undefined:first,last,find*,sample,max/min,mean,median,mode,extent,variance,stdDev, … sum→0,product→1for empty arrayszip/zipWith/zipManystop at the shortest input;zipLongestpads withundefinedbinarySearchassumes ascending sorted input- Equality helpers do not deep-compare objects
🔁 Migrating from 1.x
| Removed in 2.0 | Use instead |
| -------------- | ---------------------------- |
| nth | at |
| indexBy | keyBy |
| rest | tail |
| choice | sample |
| uniqueBy | unique (optional selector) |
Also: Node engine is now >=20.
📘 TypeScript types
import type { Comparator, EqualityComparator, Iteratee, OrderDirection, Predicate, RandomSource, Selector, SortValue, TypeGuardPredicate } from '@devxbhuvn/array-fns';| Type | Meaning |
| -------------------------- | -------------------------------------------------------------------- |
| Predicate<T> | (value, index, array) => boolean |
| TypeGuardPredicate<T, S> | Narrowing predicate for filter / find / findLast / takeWhile |
| Selector<T, K> | (value, index, array) => PropertyKey |
| Iteratee<T, R> | Map a value to another result |
| Comparator<T> | (a, b) => number for sorting |
| EqualityComparator<T> | (a, b) => boolean (true = equal) |
| OrderDirection | 'asc' \| 'desc' |
| SortValue | Values supported by sortBy / orderBy selectors |
| RandomSource | () => number in [0, 1) |
📤 Package output
- ESM + CommonJS builds
- TypeScript declaration files
- Per-function deep entry points (
@devxbhuvn/array-fns/<name>) CHANGELOG.mdincluded in the published package- Marked
sideEffects: falsefor tree-shaking
📄 License
MIT
