More Array Methods
We have seen the main transformation and search methods. JavaScript arrays have several more methods that come up in everyday work.
forEach: Iteration with Side Effects
The forEach method executes a function for each element but does not return anything:
const numbers = [1, 2, 3];
numbers.forEach((n) => console.log(n));
// 1
// 2
// 3
Use forEach when you need side effects (logging, updating external state) rather than transforming data:
const cart = [
{ name: "Apple", price: 1.5 },
{ name: "Banana", price: 0.75 },
];
let total = 0;
cart.forEach((item) => {
total += item.price;
});
console.log(total); // 2.25
flat: Flatten Nested Arrays
The flat method creates a new array with nested arrays flattened:
const nested = [1, [2, 3], [4, [5, 6]]];
console.log(nested.flat()); // [1, 2, 3, 4, [5, 6]]
console.log(nested.flat(2)); // [1, 2, 3, 4, 5, 6]
console.log(nested.flat(Infinity)); // Flatten all levels
This is useful when the data is grouped:
const departments = [
{ name: "Engineering", employees: ["Alice", "Bob"] },
{ name: "Sales", employees: ["Charlie", "Diana"] },
];
const allEmployees = departments.map((d) => d.employees).flat();
console.log(allEmployees); // ['Alice', 'Bob', 'Charlie', 'Diana']
flatMap: Map Then Flatten
The flatMap method combines map and flat(1) in one step:
const sentences = ["Hello world", "How are you"];
const words = sentences.flatMap((s) => s.split(" "));
console.log(words); // ['Hello', 'world', 'How', 'are', 'you']
// Equivalent to:
const words2 = sentences.map((s) => s.split(" ")).flat();
It is useful when your map function returns arrays:
const users = [
{ name: "Alice", hobbies: ["reading", "gaming"] },
{ name: "Bob", hobbies: ["cooking"] },
];
const allHobbies = users.flatMap((u) => u.hobbies);
console.log(allHobbies); // ['reading', 'gaming', 'cooking']
sort: Ordering Elements
The sort method sorts an array in place and returns it:
const fruits = ["banana", "apple", "cherry"];
fruits.sort();
console.log(fruits); // ['apple', 'banana', 'cherry']
Warning: Default sort converts elements to strings, which sorts numbers in lexicographic order instead of numeric order:
const numbers = [10, 2, 5, 1, 9];
numbers.sort();
console.log(numbers); // [1, 10, 2, 5, 9] - Wrong!
Provide a compare function for correct numeric sorting:
const numbers = [10, 2, 5, 1, 9];
numbers.sort((a, b) => a - b); // Ascending
console.log(numbers); // [1, 2, 5, 9, 10]
numbers.sort((a, b) => b - a); // Descending
console.log(numbers); // [10, 9, 5, 2, 1]
Sorting objects by a property:
const users = [
{ name: "Charlie", age: 25 },
{ name: "Alice", age: 30 },
{ name: "Bob", age: 20 },
];
users.sort((a, b) => a.age - b.age);
console.log(users.map((u) => u.name)); // ['Bob', 'Charlie', 'Alice']
reverse: Reversing Order
The reverse method reverses an array in place:
const letters = ["a", "b", "c"];
letters.reverse();
console.log(letters); // ['c', 'b', 'a']
Like sort, it mutates the original array. Use toReversed() (ES2023) or [...array].reverse() for a non-mutating version.
slice: Extracting Portions
The slice method returns a shallow copy of a portion of an array:
const numbers = [0, 1, 2, 3, 4, 5];
console.log(numbers.slice(2)); // [2, 3, 4, 5] - from index 2
console.log(numbers.slice(1, 4)); // [1, 2, 3] - from 1 to 4 (exclusive)
console.log(numbers.slice(-2)); // [4, 5] - last 2 elements
console.log(numbers.slice(0, -1)); // [0, 1, 2, 3, 4] - all but last
slice does not modify the original array, so we can use it to make a copy:
const copy = numbers.slice(); // Full copy
concat: Combining Arrays
The concat method merges arrays without modifying the originals:
const a = [1, 2];
const b = [3, 4];
const c = [5, 6];
const combined = a.concat(b, c);
console.log(combined); // [1, 2, 3, 4, 5, 6]
console.log(a); // [1, 2] - unchanged
The spread operator is often shorter for this:
const combined = [...a, ...b, ...c];
Method Chaining Summary
These methods can be chained together into a data pipeline:
const orders = [
{ product: "Laptop", amount: 999, status: "shipped" },
{ product: "Phone", amount: 699, status: "pending" },
{ product: "Tablet", amount: 449, status: "shipped" },
{ product: "Watch", amount: 299, status: "shipped" },
];
const shippedTotal = orders
.filter((o) => o.status === "shipped")
.map((o) => o.amount)
.reduce((sum, amount) => sum + amount, 0);
console.log(shippedTotal); // 1747