JavaScript Array Methods Cheat Sheet
Covers core iteration and transformation methods on arrays, including map, filter, reduce, the find/some/every family, and mutating versus non-mutating operations.
map, filter, reduce
The core trio for transforming arrays without mutation.
const nums = [1, 2, 3, 4, 5];nums.map(n => n * 2); // [2, 4, 6, 8, 10] -- new array, same lengthnums.filter(n => n % 2 === 0); // [2, 4] -- new array, matching elements onlynums.reduce((sum, n) => sum + n, 0); // 15 -- folds to a single valuenums.reduce((acc, n) => { // Build an object acc[n] = n * n; return acc;}, {}); // {1:1, 2:4, 3:9, 4:16, 5:25}// Chainingnums.filter(n => n % 2 === 0).map(n => n * 10); // [20, 40]
find, findIndex, some, every, includes
Locate elements or test conditions across an array.
const users = [ { id: 1, name: "Alice", active: true }, { id: 2, name: "Bob", active: false },];users.find(u => u.id === 2); // { id: 2, name: "Bob", ... } or undefinedusers.findIndex(u => u.id === 2); // 1 (index) or -1users.some(u => u.active); // true -- at least one matchesusers.every(u => u.active); // false -- not all match[1, 2, 3].includes(2); // true -- value membership check
Mutating Methods (Modify in Place)
These change the original array and return something else.
const arr = [3, 1, 2];arr.push(4); // [3, 1, 2, 4] -- add to end, returns new lengtharr.pop(); // [3, 1, 2] -- remove from end, returns removed itemarr.unshift(0); // [0, 3, 1, 2] -- add to startarr.shift(); // [3, 1, 2] -- remove from startarr.sort(); // Mutates! Default sort is lexicographic (string) orderarr.sort((a, b) => a - b); // Numeric ascending sort -- always pass a comparator for numbersarr.splice(1, 1, "x", "y"); // At index 1, remove 1 item, insert "x","y"arr.reverse(); // Mutates in place
Non-Mutating Alternatives (ES2023)
Newer methods that leave the original array untouched.
const arr = [3, 1, 2];arr.toSorted((a, b) => a - b); // [1, 2, 3] -- arr itself unchangedarr.toReversed(); // New reversed arrayarr.with(0, 99); // New array with index 0 replaced by 99// Combine & flatten[1, [2, 3], [4, [5]]].flat(); // [1, 2, 3, 4, [5]] -- flattens 1 level by default[1, [2, 3], [4, [5]]].flat(Infinity); // [1, 2, 3, 4, 5][1, 2].flatMap(n => [n, n * 10]); // [1, 10, 2, 20] -- map then flatten 1 level
Quick Reference
Other frequently used array methods.
- Array.from({length: 5}, (_, i) => i)- Build an array from an array-like/iterable, with an optional mapper
- Array.isArray(x)- Reliable check for array type
- arr.join(', ')- Concatenate elements into a string with a separator
- arr.slice(1, 3)- Non-mutating: extract a sub-array by index range
- arr.indexOf(x)- Find the first index of a primitive value, -1 if absent
- arr.at(-1)- Access from the end using negative indices (ES2022)
Object.groupBy & Map.groupBy (ES2024)
Partition an array into buckets keyed by a callback's return value.
const items = [ { name: "apple", type: "fruit" }, { name: "carrot", type: "veg" }, { name: "banana", type: "fruit" },];Object.groupBy(items, item => item.type);// { fruit: [apple, banana], veg: [carrot] } -- plain null-prototype objectMap.groupBy(items, item => item.type);// Map { 'fruit' => [apple, banana], 'veg' => [carrot] } -- preserves insertion order,// and allows non-string keys (objects, numbers) unlike Object.groupBy
entries(), keys(), values()
Get index/value iterators without manually tracking a counter.
const letters = ["a", "b", "c"];for (const [index, value] of letters.entries()) { console.log(index, value); // 0 a, 1 b, 2 c}[...letters.keys()]; // [0, 1, 2][...letters.values()]; // ['a', 'b', 'c'] -- same as spreading the array itself// Useful for destructuring in a for..of without a separate counter variable,// and composes with other iterator helpers (e.g. Iterator.prototype.map in newer engines)
copyWithin & fill (In-Place Buffer Ops)
Low-level mutating methods most often seen with typed arrays.
const arr = [1, 2, 3, 4, 5];arr.fill(0, 2); // [1, 2, 0, 0, 0] -- fill with 0 from index 2 to endarr.fill(9, 0, 2); // [9, 9, 0, 0, 0] -- fill indices [0,2)const buf = [1, 2, 3, 4, 5];buf.copyWithin(0, 3); // [4, 5, 3, 4, 5] -- copies [3..end) to start, in place// Common in performance-sensitive code operating on Float64Array/Int32Array// buffers where allocating a new array per operation would be wasteful.
Performance: Loops vs Chained Methods
Each chained call allocates a new intermediate array -- know when that cost matters.
// Chaining allocates 2 intermediate arrays for a 1M-element input:const result = bigArray.filter(x => x > 0).map(x => x * 2);// A single reduce (or manual loop) avoids the intermediate allocations:const result2 = bigArray.reduce((acc, x) => { if (x > 0) acc.push(x * 2); return acc;}, []);// For hot paths on very large arrays, a plain for loop is fastest because it// avoids per-element callback invocation overhead entirely:const out = [];for (let i = 0; i < bigArray.length; i++) { if (bigArray[i] > 0) out.push(bigArray[i] * 2);}// Rule of thumb: reach for readability (map/filter/reduce) first; only drop// to manual loops after profiling shows the array processing is a hot path.
Lesser-Known Methods & Gotchas
Behaviors that differ from what beginner examples usually show.
- reduceRight- Like reduce but folds right-to-left; useful for right-associative operations like function composition
- Array.of(7)- Creates [7] (single element); contrast with new Array(7) which creates a length-7 sparse array of empty slots
- Sparse array holes- forEach/map/filter SKIP holes entirely, but a plain for loop or for..of visits them as undefined
- Stable sort- Array.prototype.sort() has been a stable sort (equal elements keep relative order) since ES2019 in all modern engines
- includes() vs indexOf()- includes() finds NaN using SameValueZero; [NaN].indexOf(NaN) returns -1 but [NaN].includes(NaN) returns true
- at(-1)- Cleaner than arr[arr.length - 1]; also works identically on strings and typed arrays
- toSpliced(start, count, ...items)- ES2023 non-mutating counterpart to splice(); returns a new array, leaves the original untouched
Array.prototype.sort() converts elements to strings and sorts lexicographically by default -- [10, 2, 1].sort() gives [1, 10, 2], not numeric order -- so always pass a comparator like (a, b) => a - b for numbers.