JavaScript arrays have powerful built-in methods for transforming and manipulating data. Here's a comprehensive guide.
Transforming Arrays#
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
6// With index
7const indexed = numbers.map((n, i) => `${i}: ${n}`);
8// ['0: 1', '1: 2', '2: 3', '3: 4', '4: 5']
9
10// Object transformation
11const users = [{ name: 'John' }, { name: 'Jane' }];
12const names = users.map(u => u.name);
13// ['John', 'Jane']Filtering Arrays#
1// filter - keep elements that pass test
2const numbers = [1, 2, 3, 4, 5, 6];
3const evens = numbers.filter(n => n % 2 === 0);
4// [2, 4, 6]
5
6// Filter objects
7const users = [
8 { name: 'John', active: true },
9 { name: 'Jane', active: false },
10 { name: 'Bob', active: true },
11];
12
13const activeUsers = users.filter(u => u.active);
14// [{ name: 'John', active: true }, { name: 'Bob', active: true }]
15
16// Remove falsy values
17const mixed = [0, 1, '', 'hello', null, undefined, false, true];
18const truthy = mixed.filter(Boolean);
19// [1, 'hello', true]Reducing Arrays#
1// reduce - accumulate to single value
2const numbers = [1, 2, 3, 4, 5];
3
4// Sum
5const sum = numbers.reduce((acc, n) => acc + n, 0);
6// 15
7
8// Max value
9const max = numbers.reduce((a, b) => Math.max(a, b));
10// 5
11
12// Group by property
13const people = [
14 { name: 'John', age: 25 },
15 { name: 'Jane', age: 25 },
16 { name: 'Bob', age: 30 },
17];
18
19const byAge = people.reduce((groups, person) => {
20 const key = person.age;
21 groups[key] = groups[key] || [];
22 groups[key].push(person);
23 return groups;
24}, {});
25// { 25: [...], 30: [...] }
26
27// Count occurrences
28const fruits = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple'];
29const counts = fruits.reduce((acc, fruit) => {
30 acc[fruit] = (acc[fruit] || 0) + 1;
31 return acc;
32}, {});
33// { apple: 3, banana: 2, orange: 1 }Finding Elements#
1const users = [
2 { id: 1, name: 'John' },
3 { id: 2, name: 'Jane' },
4 { id: 3, name: 'Bob' },
5];
6
7// find - first matching element
8const john = users.find(u => u.name === 'John');
9// { id: 1, name: 'John' }
10
11// findIndex - index of first match
12const janeIndex = users.findIndex(u => u.name === 'Jane');
13// 1
14
15// findLast - last matching element
16const numbers = [1, 2, 3, 2, 1];
17const lastTwo = numbers.findLast(n => n === 2);
18// 2 (at index 3)
19
20// findLastIndex - index of last match
21const lastTwoIndex = numbers.findLastIndex(n => n === 2);
22// 3
23
24// includes - check if exists
25const hasJohn = users.some(u => u.name === 'John');
26// trueTesting Elements#
1const numbers = [1, 2, 3, 4, 5];
2
3// some - at least one passes
4const hasEven = numbers.some(n => n % 2 === 0);
5// true
6
7// every - all pass
8const allPositive = numbers.every(n => n > 0);
9// true
10
11const allEven = numbers.every(n => n % 2 === 0);
12// false
13
14// includes - value exists
15const hasThree = numbers.includes(3);
16// true
17
18const hasTen = numbers.includes(10);
19// falseFlattening Arrays#
1// flat - flatten nested arrays
2const nested = [1, [2, 3], [4, [5, 6]]];
3
4nested.flat(); // [1, 2, 3, 4, [5, 6]]
5nested.flat(2); // [1, 2, 3, 4, 5, 6]
6nested.flat(Infinity); // Flatten all levels
7
8// flatMap - map then flatten
9const sentences = ['Hello world', 'How are you'];
10const words = sentences.flatMap(s => s.split(' '));
11// ['Hello', 'world', 'How', 'are', 'you']
12
13// Without flatMap
14const words2 = sentences.map(s => s.split(' ')).flat();
15// Same resultSorting Arrays#
1// sort - mutates original array
2const numbers = [3, 1, 4, 1, 5, 9];
3numbers.sort((a, b) => a - b); // Ascending
4// [1, 1, 3, 4, 5, 9]
5
6numbers.sort((a, b) => b - a); // Descending
7// [9, 5, 4, 3, 1, 1]
8
9// Sort strings
10const names = ['John', 'jane', 'Bob'];
11names.sort((a, b) => a.localeCompare(b));
12// ['Bob', 'jane', 'John']
13
14// Sort objects
15const users = [
16 { name: 'John', age: 30 },
17 { name: 'Jane', age: 25 },
18 { name: 'Bob', age: 35 },
19];
20
21users.sort((a, b) => a.age - b.age);
22// Sorted by age ascending
23
24// toSorted - non-mutating (ES2023)
25const sorted = numbers.toSorted((a, b) => a - b);
26// Original unchangedAdding/Removing Elements#
1const arr = [1, 2, 3];
2
3// push - add to end (mutates)
4arr.push(4); // [1, 2, 3, 4]
5
6// pop - remove from end (mutates)
7const last = arr.pop(); // 4, arr = [1, 2, 3]
8
9// unshift - add to start (mutates)
10arr.unshift(0); // [0, 1, 2, 3]
11
12// shift - remove from start (mutates)
13const first = arr.shift(); // 0, arr = [1, 2, 3]
14
15// splice - add/remove at index (mutates)
16arr.splice(1, 1); // Remove 1 element at index 1
17arr.splice(1, 0, 'new'); // Insert at index 1
18
19// toSpliced - non-mutating (ES2023)
20const modified = arr.toSpliced(1, 1, 'replaced');Copying and Slicing#
1const arr = [1, 2, 3, 4, 5];
2
3// slice - extract portion (non-mutating)
4arr.slice(1, 3); // [2, 3]
5arr.slice(-2); // [4, 5]
6arr.slice(2); // [3, 4, 5]
7
8// Shallow copy
9const copy = arr.slice();
10const copy2 = [...arr];
11const copy3 = Array.from(arr);
12
13// concat - merge arrays (non-mutating)
14const merged = [1, 2].concat([3, 4], [5, 6]);
15// [1, 2, 3, 4, 5, 6]
16
17// Spread alternative
18const merged2 = [...[1, 2], ...[3, 4]];Reversing Arrays#
1const arr = [1, 2, 3, 4, 5];
2
3// reverse - mutates original
4arr.reverse(); // [5, 4, 3, 2, 1]
5
6// toReversed - non-mutating (ES2023)
7const reversed = arr.toReversed();
8// Original unchanged
9
10// Non-mutating alternative
11const reversed2 = [...arr].reverse();Iterating#
1const arr = [1, 2, 3];
2
3// forEach - side effects
4arr.forEach((item, index) => {
5 console.log(`${index}: ${item}`);
6});
7
8// entries - [index, value] pairs
9for (const [index, value] of arr.entries()) {
10 console.log(`${index}: ${value}`);
11}
12
13// keys - indices
14for (const index of arr.keys()) {
15 console.log(index); // 0, 1, 2
16}
17
18// values - values
19for (const value of arr.values()) {
20 console.log(value); // 1, 2, 3
21}Creating Arrays#
1// Array.from - from iterable or array-like
2Array.from('hello'); // ['h', 'e', 'l', 'l', 'o']
3Array.from({ length: 5 }, (_, i) => i); // [0, 1, 2, 3, 4]
4Array.from(new Set([1, 2, 2, 3])); // [1, 2, 3]
5
6// Array.of - create from arguments
7Array.of(1, 2, 3); // [1, 2, 3]
8Array.of(5); // [5] (not [,,,,,])
9
10// fill - fill with value
11new Array(3).fill(0); // [0, 0, 0]
12[1, 2, 3].fill('x'); // ['x', 'x', 'x']
13[1, 2, 3, 4].fill('x', 1, 3); // [1, 'x', 'x', 4]Array.at()#
1const arr = [1, 2, 3, 4, 5];
2
3// Positive index
4arr.at(0); // 1
5arr.at(2); // 3
6
7// Negative index (from end)
8arr.at(-1); // 5
9arr.at(-2); // 4
10
11// Cleaner than arr[arr.length - 1]Chaining Methods#
1const users = [
2 { name: 'John', age: 25, active: true },
3 { name: 'Jane', age: 30, active: false },
4 { name: 'Bob', age: 35, active: true },
5 { name: 'Alice', age: 28, active: true },
6];
7
8// Chain operations
9const result = users
10 .filter(u => u.active)
11 .map(u => u.name)
12 .sort()
13 .join(', ');
14// 'Alice, Bob, John'
15
16// Get average age of active users
17const avgAge = users
18 .filter(u => u.active)
19 .reduce((sum, u, _, arr) => sum + u.age / arr.length, 0);
20// 29.33...Best Practices#
Immutability:
✓ Prefer non-mutating methods
✓ Use toSorted, toReversed, toSpliced
✓ Spread for shallow copies
✓ Return new arrays from functions
Performance:
✓ Use for loops for large arrays
✓ Avoid chaining on huge datasets
✓ Use appropriate method for task
✓ Consider Set for uniqueness
Readability:
✓ Chain related operations
✓ Use meaningful variable names
✓ Break complex chains
✓ Comment non-obvious logic
Avoid:
✗ Mutating in map/filter callbacks
✗ forEach for transformations
✗ Ignoring return values
✗ Nested loops when avoidable
Conclusion#
JavaScript array methods provide powerful, expressive ways to work with collections. Use map for transformation, filter for selection, reduce for aggregation, and find for searching. Prefer non-mutating methods and chaining for cleaner code. For performance-critical code with large arrays, consider traditional loops.