JavaScript arrays have powerful built-in methods. Here's how to use them effectively.
Transformation Methods#
1// map - Transform each element
2const numbers = [1, 2, 3, 4, 5];
3const doubled = numbers.map(n => n * 2);
4// [2, 4, 6, 8, 10]
5
6const users = [
7 { name: 'John', age: 30 },
8 { name: 'Jane', age: 25 },
9];
10const names = users.map(user => user.name);
11// ['John', 'Jane']
12
13// With index
14const indexed = numbers.map((n, i) => `${i}: ${n}`);
15// ['0: 1', '1: 2', '2: 3', '3: 4', '4: 5']
16
17// filter - Keep elements that pass test
18const evens = numbers.filter(n => n % 2 === 0);
19// [2, 4]
20
21const adults = users.filter(user => user.age >= 18);
22
23// Chaining map and filter
24const adultNames = users
25 .filter(user => user.age >= 18)
26 .map(user => user.name);
27
28// flatMap - Map and flatten
29const sentences = ['Hello world', 'How are you'];
30const words = sentences.flatMap(s => s.split(' '));
31// ['Hello', 'world', 'How', 'are', 'you']
32
33// Useful for optional results
34const results = [1, 2, 3].flatMap(n =>
35 n > 1 ? [n, n * 2] : []
36);
37// [2, 4, 3, 6]Reduce#
1// Sum array
2const sum = numbers.reduce((acc, n) => acc + n, 0);
3// 15
4
5// Find max
6const max = numbers.reduce((a, b) => Math.max(a, b));
7// 5
8
9// Group by property
10const items = [
11 { category: 'fruit', name: 'apple' },
12 { category: 'fruit', name: 'banana' },
13 { category: 'vegetable', name: 'carrot' },
14];
15
16const grouped = items.reduce((acc, item) => {
17 const key = item.category;
18 acc[key] = acc[key] || [];
19 acc[key].push(item);
20 return acc;
21}, {});
22// { fruit: [...], vegetable: [...] }
23
24// Count occurrences
25const votes = ['yes', 'no', 'yes', 'yes', 'no'];
26const counts = votes.reduce((acc, vote) => {
27 acc[vote] = (acc[vote] || 0) + 1;
28 return acc;
29}, {});
30// { yes: 3, no: 2 }
31
32// Build object from array
33const pairs = [['a', 1], ['b', 2], ['c', 3]];
34const obj = pairs.reduce((acc, [key, value]) => {
35 acc[key] = value;
36 return acc;
37}, {});
38// { a: 1, b: 2, c: 3 }
39
40// Alternative: Object.fromEntries(pairs)
41
42// Pipe functions
43const pipe = (...fns) => x => fns.reduce((v, f) => f(v), x);
44
45const add1 = x => x + 1;
46const double = x => x * 2;
47const square = x => x * x;
48
49const compute = pipe(add1, double, square);
50compute(2); // ((2 + 1) * 2) ^ 2 = 36Finding Elements#
1// find - First matching element
2const users = [
3 { id: 1, name: 'John' },
4 { id: 2, name: 'Jane' },
5 { id: 3, name: 'Bob' },
6];
7
8const jane = users.find(u => u.name === 'Jane');
9// { id: 2, name: 'Jane' }
10
11const notFound = users.find(u => u.name === 'Alice');
12// undefined
13
14// findIndex - Index of first match
15const janeIndex = users.findIndex(u => u.name === 'Jane');
16// 1
17
18// findLast / findLastIndex (ES2023)
19const numbers = [1, 2, 3, 2, 1];
20const lastTwo = numbers.findLast(n => n === 2);
21// 2 (the second occurrence)
22
23// includes - Check existence
24const hasTwo = numbers.includes(2);
25// true
26
27// indexOf / lastIndexOf
28const firstIndex = numbers.indexOf(2);
29// 1
30const lastIndex = numbers.lastIndexOf(2);
31// 3
32
33// some - At least one matches
34const hasEven = numbers.some(n => n % 2 === 0);
35// true
36
37// every - All match
38const allPositive = numbers.every(n => n > 0);
39// trueSorting#
1// sort - Mutates original array!
2const nums = [3, 1, 4, 1, 5, 9];
3nums.sort((a, b) => a - b); // Ascending
4// [1, 1, 3, 4, 5, 9]
5
6nums.sort((a, b) => b - a); // Descending
7// [9, 5, 4, 3, 1, 1]
8
9// Sort strings
10const names = ['Charlie', 'Alice', 'Bob'];
11names.sort(); // Alphabetical
12// ['Alice', 'Bob', 'Charlie']
13
14names.sort((a, b) => a.localeCompare(b)); // Locale-aware
15
16// Sort objects
17const users = [
18 { name: 'John', age: 30 },
19 { name: 'Jane', age: 25 },
20 { name: 'Bob', age: 35 },
21];
22
23users.sort((a, b) => a.age - b.age);
24// By age ascending
25
26users.sort((a, b) => a.name.localeCompare(b.name));
27// By name
28
29// Non-mutating sort with toSorted (ES2023)
30const sorted = nums.toSorted((a, b) => a - b);
31// Original unchanged
32
33// reverse - Mutates!
34const reversed = [1, 2, 3].reverse();
35// [3, 2, 1]
36
37// toReversed (ES2023) - Non-mutating
38const reversedCopy = [1, 2, 3].toReversed();Adding and Removing#
1// push - Add to end (mutates)
2const arr = [1, 2, 3];
3arr.push(4);
4// [1, 2, 3, 4]
5
6// pop - Remove from end (mutates)
7const last = arr.pop();
8// 4, arr is [1, 2, 3]
9
10// unshift - Add to beginning (mutates)
11arr.unshift(0);
12// [0, 1, 2, 3]
13
14// shift - Remove from beginning (mutates)
15const first = arr.shift();
16// 0, arr is [1, 2, 3]
17
18// splice - Insert/remove at index (mutates)
19arr.splice(1, 1); // Remove 1 element at index 1
20// arr is [1, 3]
21
22arr.splice(1, 0, 2); // Insert 2 at index 1
23// arr is [1, 2, 3]
24
25arr.splice(1, 1, 'a', 'b'); // Replace 1 element with 2
26// arr is [1, 'a', 'b', 3]
27
28// toSpliced (ES2023) - Non-mutating
29const newArr = arr.toSpliced(1, 1, 'x');
30
31// concat - Combine arrays (non-mutating)
32const combined = [1, 2].concat([3, 4], [5]);
33// [1, 2, 3, 4, 5]
34
35// Spread operator (preferred)
36const combined2 = [...[1, 2], ...[3, 4]];
37
38// slice - Extract portion (non-mutating)
39const arr2 = [1, 2, 3, 4, 5];
40const middle = arr2.slice(1, 4);
41// [2, 3, 4]
42
43const lastTwo = arr2.slice(-2);
44// [4, 5]
45
46const copy = arr2.slice(); // Shallow copyFlattening#
1// flat - Flatten nested arrays
2const nested = [1, [2, [3, [4]]]];
3
4nested.flat();
5// [1, 2, [3, [4]]]
6
7nested.flat(2);
8// [1, 2, 3, [4]]
9
10nested.flat(Infinity);
11// [1, 2, 3, 4]
12
13// flatMap - Map then flatten one level
14const data = [
15 { items: [1, 2] },
16 { items: [3, 4] },
17];
18
19const allItems = data.flatMap(d => d.items);
20// [1, 2, 3, 4]Iteration#
1// forEach - No return value
2const arr = [1, 2, 3];
3arr.forEach((item, index) => {
4 console.log(`${index}: ${item}`);
5});
6
7// for...of - Iterable
8for (const item of arr) {
9 console.log(item);
10}
11
12// With index
13for (const [index, item] of arr.entries()) {
14 console.log(`${index}: ${item}`);
15}
16
17// keys and values
18for (const key of arr.keys()) {
19 console.log(key); // 0, 1, 2
20}
21
22for (const value of arr.values()) {
23 console.log(value); // 1, 2, 3
24}Creating Arrays#
1// Array.from - Create from iterable
2const set = new Set([1, 2, 3]);
3const fromSet = Array.from(set);
4
5// With map function
6const squares = Array.from([1, 2, 3], x => x * x);
7// [1, 4, 9]
8
9// Create range
10const range = Array.from({ length: 5 }, (_, i) => i);
11// [0, 1, 2, 3, 4]
12
13// Array.of - Create from arguments
14const arr = Array.of(1, 2, 3);
15// [1, 2, 3]
16
17// fill - Fill with value
18const filled = new Array(5).fill(0);
19// [0, 0, 0, 0, 0]
20
21// Be careful with objects!
22const bad = new Array(3).fill([]);
23bad[0].push(1);
24// [[1], [1], [1]] - Same reference!
25
26const good = Array.from({ length: 3 }, () => []);
27good[0].push(1);
28// [[1], [], []]Practical Examples#
1// Remove duplicates
2const unique = [...new Set([1, 2, 2, 3, 3, 3])];
3// [1, 2, 3]
4
5// Chunk array
6function chunk(arr, size) {
7 return Array.from(
8 { length: Math.ceil(arr.length / size) },
9 (_, i) => arr.slice(i * size, i * size + size)
10 );
11}
12chunk([1, 2, 3, 4, 5], 2);
13// [[1, 2], [3, 4], [5]]
14
15// Shuffle array
16function shuffle(arr) {
17 const copy = [...arr];
18 for (let i = copy.length - 1; i > 0; i--) {
19 const j = Math.floor(Math.random() * (i + 1));
20 [copy[i], copy[j]] = [copy[j], copy[i]];
21 }
22 return copy;
23}
24
25// Intersection
26const intersection = (a, b) => a.filter(x => b.includes(x));
27
28// Difference
29const difference = (a, b) => a.filter(x => !b.includes(x));
30
31// Union
32const union = (a, b) => [...new Set([...a, ...b])];Best Practices#
Immutability:
✓ Prefer non-mutating methods
✓ Use spread or toSorted/toSpliced
✓ Create copies when needed
✓ Avoid modifying in forEach
Performance:
✓ Avoid multiple iterations
✓ Chain methods efficiently
✓ Use for loop for performance-critical code
✓ Consider early returns with find/some
Readability:
✓ Use descriptive callback names
✓ Break long chains into variables
✓ Choose the right method for the task
✓ Keep callbacks simple
Conclusion#
JavaScript array methods enable functional, expressive code. Use map for transformations, filter for selection, reduce for aggregation, and find for searching. Prefer non-mutating methods and chain operations for clean, readable code.