JavaScript arrays come with over 30 built-in methods, yet most developers rely on just a handful. Mastering the full arsenal — from the classic map/filter/reduce trio to modern additions like findLast(), at(), and Array.from() — makes your code more declarative, readable, and often faster. This guide covers every method worth knowing with production-ready examples.
⚡ TL;DR: map() transforms, filter() selects, reduce() aggregates. find() returns first match, some()/every() check conditions. flat() and flatMap() handle nested arrays. Array.from() creates arrays from any iterable. at(-1) gets last element. Sort uses localeCompare for strings.
Transformation: map, flatMap, flat
const orders = [
{ id: 1, items: ['apple', 'banana'], total: 15.99 },
{ id: 2, items: ['cherry'], total: 5.49 },
{ id: 3, items: ['date', 'elderberry', 'fig'], total: 22.00 }
];
// map: transform each element
const totals = orders.map(o => o.total); // [15.99, 5.49, 22.00]
const summaries = orders.map(({ id, total }) => ({ id, total: total.toFixed(2) }));
// flat: flatten nested arrays
const allItems = orders.map(o => o.items).flat();
// ['apple','banana','cherry','date','elderberry','fig']
// flatMap: map then flat (1 level) — more efficient than .map().flat()
const allItemsFM = orders.flatMap(o => o.items);
// Same result, single pass
// flat with depth:
const nested = [1, [2, [3, [4]]]];
nested.flat(); // [1, 2, [3, [4]]] (depth 1)
nested.flat(2); // [1, 2, 3, [4]] (depth 2)
nested.flat(Infinity); // [1, 2, 3, 4] (all levels)
Filtering and searching
const users = [
{ id:1, name:'Alice', role:'admin', active:true, age:32 },
{ id:2, name:'Bob', role:'user', active:false, age:25 },
{ id:3, name:'Carol', role:'user', active:true, age:28 },
{ id:4, name:'Dave', role:'admin', active:true, age:41 },
];
// filter: select matching elements
const activeAdmins = users.filter(u => u.active && u.role === 'admin');
// [Alice, Dave]
// find: first matching element (undefined if none)
const firstAdmin = users.find(u => u.role === 'admin'); // Alice
// findIndex: index of first match (-1 if none)
const firstAdminIdx = users.findIndex(u => u.role === 'admin'); // 0
// findLast / findLastIndex (ES2023): search from the END
const lastAdmin = users.findLast(u => u.role === 'admin'); // Dave
const lastAdminIdx = users.findLastIndex(u => u.role === 'admin'); // 3
// some: true if ANY element matches
const hasInactive = users.some(u => !u.active); // true
// every: true if ALL elements match
const allActive = users.every(u => u.active); // false
// includes: check if value exists (uses ===)
[1, 2, 3].includes(2); // true
['a', 'b', 'c'].includes('d'); // false
Aggregation: reduce and reduceRight
// reduce: fold array into single value
const total = orders.reduce((sum, order) => sum + order.total, 0);
// 43.48
// Group by category:
const grouped = users.reduce((acc, user) => {
const key = user.role;
acc[key] = acc[key] || [];
acc[key].push(user);
return acc;
}, {});
// { admin: [Alice, Dave], user: [Bob, Carol] }
// Count occurrences:
const roleCounts = users.reduce((acc, u) => {
acc[u.role] = (acc[u.role] || 0) + 1;
return acc;
}, {});
// { admin: 2, user: 2 }
// Flatten and transform in one pass:
const result = orders.reduce((acc, order) => {
order.items.forEach(item => acc.push({ item, orderId: order.id }));
return acc;
}, []);
// [{item:'apple',orderId:1}, {item:'banana',orderId:1}, ...]
Sorting — the tricky one
// Default sort converts to strings — WRONG for numbers!
[10, 2, 21, 1].sort(); // [1, 10, 2, 21] (lexicographic!) WRONG
[10, 2, 21, 1].sort((a,b) => a - b); // [1, 2, 10, 21] CORRECT
// Sort strings correctly:
['banana','apple','cherry'].sort(); // ['apple','banana','cherry'] (works for ASCII)
['ä','z','a'].sort(); // Wrong for non-ASCII!
['ä','z','a'].sort((a,b) => a.localeCompare(b)); // ['a','ä','z'] CORRECT
// Sort objects:
users.sort((a,b) => a.age - b.age); // By age ascending
users.sort((a,b) => b.age - a.age); // By age descending
users.sort((a,b) => a.name.localeCompare(b.name)); // Alphabetical
// Stable sort guaranteed in modern JS (ES2019+):
// If two elements compare equal, their original order is preserved
// Sort by role, then by name within same role:
users.sort((a,b) => a.role.localeCompare(b.role) || a.name.localeCompare(b.name));
Array creation and conversion
// Array.from: create from any iterable or array-like
Array.from('hello'); // ['h','e','l','l','o']
Array.from({length:5}, (_, i) => i*2); // [0,2,4,6,8]
Array.from(new Set([1,2,2,3,3])); // [1,2,3] (deduplicate)
Array.from(document.querySelectorAll('p')); // NodeList to Array
// Array.of: create array from arguments (unlike Array constructor)
Array.of(3); // [3] (one element)
Array(3); // [,,] (sparse array of length 3!)
Array.of(1,2,3); // [1,2,3]
// at(): access by index, supports negative
const arr = [1,2,3,4,5];
arr.at(0); // 1 (same as arr[0])
arr.at(-1); // 5 (LAST element — no more arr[arr.length-1])
arr.at(-2); // 4
// Spread to copy/combine:
const copy = [...arr];
const combined = [...arr1, ...arr2];
const withExtra = [...arr, 6, 7];
Mutation methods — use with caution
// These MUTATE the original array
const arr = [1,2,3];
arr.push(4); // Append: [1,2,3,4], returns new length
arr.pop(); // Remove last: [1,2,3], returns 4
arr.unshift(0); // Prepend: [0,1,2,3], returns new length
arr.shift(); // Remove first: [1,2,3], returns 0
arr.splice(1,1); // Remove 1 element at index 1: [1,3]
arr.splice(1,0,1.5); // Insert at index 1: [1,1.5,3]
arr.fill(0, 1, 3); // Fill indices 1-2 with 0: [1,0,0]
arr.reverse(); // Reverse in place
// IMMUTABLE alternatives (ES2023):
const arr2 = [1,2,3];
arr2.toReversed(); // New reversed array, arr2 unchanged
arr2.toSorted(); // New sorted array
arr2.toSpliced(1,1); // New array with splice applied
arr2.with(0, 99); // New array with index 0 replaced: [99,2,3]
- ✅ flatMap is more efficient than .map().flat() for 1-level flattening
- ✅ findLast/findLastIndex for searching from end (ES2023)
- ✅ at(-1) instead of arr[arr.length-1]
- ✅ toSorted/toReversed for immutable sort/reverse (ES2023)
- ✅ Always use localeCompare for string sorting with Unicode
- ❌ Never use default sort() for numbers — lexicographic order is wrong
- ❌ Never mutate arrays in React state — use spread or toSpliced()
Array methods pair with JavaScript closures — the callback functions inside map/filter/reduce are closures. For TypeScript typing, generics enable type-safe array transformations. External reference: MDN Array documentation.
Recommended Reading
→ Designing Data-Intensive Applications — The bible of distributed systems and production engineering at scale.
→ The Pragmatic Programmer — Timeless engineering wisdom every senior developer needs.
Affiliate links. We earn a small commission at no extra cost to you.
Free Weekly Newsletter
🚀 Join 2,000+ Senior Developers
Get expert-level JavaScript, Python, AWS, system design and AI secrets every week. Zero fluff, pure signal.
Discover more from CheatCoders
Subscribe to get the latest posts sent to your email.
