@r01al/array-polyfills
v1.0.8
Published
Cool JS Array Polyfills
Downloads
283
Readme
Cool Array Polyfills
✨ A tiny TypeScript library that adds useful array utilities in two ways:
- 🧩 Side-effectful
Array.prototypepolyfills (opt-in via theautoentry). - 🧰 Standalone helper functions for use without touching prototypes.
Benefits
- 🌍 Works in both modern bundlers and simple
<script>tags (UMD builds). - 🧭 Lets you choose between prototype methods or pure functions.
- ✅ Strong typing for safer use in TypeScript.
- 🍃 Small, focused helpers that are easy to tree‑shake.
Install
npm i @r01al/array-polyfillsQuick start
Standalone helpers (no prototype changes)
import {
first,
last,
unique,
chunk,
compact,
compactMap,
random,
keyValueMap,
sum,
avg,
max,
min,
shuffle,
groupBy,
flatten,
zip,
partition,
pluck,
countBy,
difference,
intersection,
union,
uniqBy,
sortBy,
sample,
pad
} from "@r01al/array-polyfills";
first([1, 2, 3]);
unique([1, 1, 2]);
chunk([1, 2, 3, 4], 2);
compact([0, 1, "", 2]);
compactMap([1, 2, 3], n => (n > 1 ? n * 2 : null));
groupBy([{ type: "a" }, { type: "b" }], "type");
flatten([1, [2, 3], 4]);
zip([1, 2], ["a", "b"]);
partition([1, 2, 3, 4], n => n % 2 === 0);
pluck([{ id: 1 }, { id: 2 }], "id");
countBy(["a", "b", "a"], value => value);
difference([1, 2, 3], [2, 4]);
intersection([1, 2, 3], [2, 3, 4]);
union([1, 2], [2, 3], [3, 4]);
uniqBy([{ id: 1 }, { id: 1 }, { id: 2 }], "id");
sortBy([{ n: 2 }, { n: 1 }], "n");
sample([1, 2, 3, 4], 2);
pad([1, 2], 5, 0);Polyfill Array.prototype
import "@r01al/array-polyfills/auto";
[1, 2, 3].first();
[1, 1, 2].unique();
[1, 2, 3, 4].chunk(2);
[0, 1, "", 2].compact();
([1, 2, 3] as number[]).compactMap(n => (n > 1 ? n * 2 : null));
[{ type: "a" }, { type: "b" }].groupBy("type");
([1, [2, 3], 4] as (number | number[])[]).flatten();
[1, 2].zip(["a", "b"]);
[1, 2, 3, 4].partition(n => n % 2 === 0);
([{ id: 1 }, { id: 2 }] as { id: number }[]).pluck("id");
["a", "b", "a"].countBy(value => value);
[1, 2, 3].difference([2, 4]);
[1, 2, 3].intersection([2, 3, 4]);
[1, 2].union([2, 3], [3, 4]);
([{ id: 1 }, { id: 1 }, { id: 2 }] as { id: number }[]).uniqBy("id");
([{ n: 2 }, { n: 1 }] as { n: number }[]).sortBy("n");
[1, 2, 3, 4].sample(2);
[1, 2].pad(5, 0);Browser (UMD via unpkg)
Auto polyfills (no module loader required):
<script src="https://unpkg.com/@r01al/array-polyfills@latest/dist/auto.umd.js"></script>
<script>
[1, 2, 3].first();
[1, 1, 2].unique();
</script>Standalone helpers (global ArrayPolyfills):
<script src="https://unpkg.com/@r01al/array-polyfills@latest/dist/index.umd.js"></script>
<script>
ArrayPolyfills.first([1, 2, 3]);
ArrayPolyfills.shuffle([1, 2, 3]);
</script>Note: UMD bundles are ES5-targeted, but older browsers may still require Map/Set polyfills.
API
All functions below can be used either as standalone helpers or as prototype methods when using the auto entry.
first
first<T>(arr: T[]): T | undefinedReturns the first element, or undefined if the array is empty.
last
last<T>(arr: T[]): T | undefinedReturns the last element, or undefined if the array is empty.
unique
unique<T>(arr: T[]): T[]Returns a new array with unique elements. Primitives are de-duplicated by value; objects use a deep equality check.
chunk
chunk<T>(arr: T[], size: number): T[][]Splits the array into chunks of size. Throws if size is not a positive integer.
compact
compact<T>(arr: T[]): T[]Returns a new array with all falsy values removed (false, 0, "", null, undefined).
Example:
compact([0, 1, "", 2, null, undefined, false, 3]);
// [1, 2, 3]compactMap
compactMap<T, R>(
arr: T[],
mapper: (value: T, index: number, arr: T[]) => R
): Exclude<R, null | undefined>[]Maps items and removes null/undefined results.
Example:
compactMap([1, 2, 3], n => (n > 1 ? n * 2 : null));
// [4, 6]random
random<T>(arr: T[]): T | undefinedReturns a random element, or undefined if the array is empty.
keyValueMap
keyValueMap<T extends Record<string, any>>(arr: T[], key: string, value: string): Record<string, any>Builds an object mapping item[key] to item[value]. Throws if key or value is missing, any element is falsy, non-object, or missing key.
Example:
keyValueMap(
[
{ id: "a", name: "Alpha" },
{ id: "b", name: "Beta" }
],
"id",
"name"
);
// { a: "Alpha", b: "Beta" }groupBy
groupBy<T, K extends PropertyKey>(
arr: T[],
key: ((item: T, index: number, arr: T[]) => K) | keyof T
): Record<K, T[]>Groups items by a property name or mapper function.
Example:
groupBy(
[
{ type: "a", value: 1 },
{ type: "b", value: 2 },
{ type: "a", value: 3 }
],
"type"
);
// { a: [{...}, {...}], b: [{...}] }pluck
pluck<T, K extends keyof T>(arr: T[], key: K): T[K][]Plucks a property value from each item.
Example:
pluck([{ id: 1 }, { id: 2 }], "id");
// [1, 2]countBy
countBy<T, K extends PropertyKey>(
arr: T[],
key: ((item: T, index: number, arr: T[]) => K) | keyof T
): Record<K, number>Counts items by a property name or mapper function.
Example:
countBy(["a", "b", "a"], value => value);
// { a: 2, b: 1 }sum
sum(arr: number[]): numberReturns the sum of all numbers. Throws if any element is not a number. Returns 0 for an empty array.
avg
avg(arr: number[]): number | undefinedReturns the average. Throws if any element is not a number. Returns undefined for an empty array.
max
max(arr: number[]): number | undefinedReturns the maximum value. Throws if any element is not a number. Returns undefined for an empty array.
min
min(arr: number[]): number | undefinedReturns the minimum value. Throws if any element is not a number. Returns undefined for an empty array.
shuffle
shuffle<T>(arr: T[]): T[]Shuffles the array in place and returns the same array reference.
flatten
flatten<T>(arr: (T | T[])[]): T[]Flattens the array by one level.
Example:
flatten([1, [2, 3], 4]);
// [1, 2, 3, 4]zip
zip<T>(arr: T[], ...arrays: any[][]): any[][]Zips arrays into tuples, truncated to the shortest array length. If no extra arrays are provided, returns single-item tuples.
Example:
zip([1, 2, 3], ["a", "b"]);
// [[1, "a"], [2, "b"]]partition
partition<T>(
arr: T[],
predicate: (value: T, index: number, arr: T[]) => boolean
): [T[], T[]]Splits items into two arrays: those that pass the predicate and those that fail.
Example:
partition([1, 2, 3, 4], n => n % 2 === 0);
// [[2, 4], [1, 3]]difference
difference<T>(arr: T[], ...arrays: T[][]): T[]Returns items that are not present in the other arrays.
Example:
difference([1, 2, 3], [2, 4]);
// [1, 3]intersection
intersection<T>(arr: T[], ...arrays: T[][]): T[]Returns items present in all arrays.
Example:
intersection([1, 2, 3], [2, 3, 4]);
// [2, 3]union
union<T>(arr: T[], ...arrays: T[][]): T[]Returns a unique merge of the array and the other arrays.
Example:
union([1, 2], [2, 3], [3, 4]);
// [1, 2, 3, 4]uniqBy
uniqBy<T, K>(
arr: T[],
key: ((item: T, index: number, arr: T[]) => K) | keyof T
): T[]Returns the first item for each unique key.
Example:
uniqBy([{ id: 1 }, { id: 1 }, { id: 2 }], "id");
// [{ id: 1 }, { id: 2 }]sortBy
sortBy<T, K extends string | number | bigint>(
arr: T[],
key: ((item: T, index: number, arr: T[]) => K) | keyof T
): T[]Returns a new array sorted by the key (stable). For dates, map to getTime() in the mapper.
Example:
sortBy([{ n: 2 }, { n: 1 }], "n");
// [{ n: 1 }, { n: 2 }]sample
sample<T>(arr: T[], count: number): T[]Returns a random sample without replacement.
Example:
sample([1, 2, 3, 4], 2);
// length 2pad
pad<T>(arr: T[], length: number, value: T): T[]Pads the array to the given length with the provided value.
Example:
pad([1, 2], 5, 0);
// [1, 2, 0, 0, 0]Notes
- The
autoentry defines methods only if they do not already exist. - The
autoentry is side-effectful by design and is listed undersideEffectsfor bundlers. - Build outputs live under
dist/for ESM, CJS, and UMD.
