JavaScript course menu
JavaScript Array Methods: map, filter, reduce, find, some, every, sort and More
Master JavaScript array methods with examples: forEach, map, filter, reduce, find and findIndex, some and every, sort with compare functions, toSorted and other non-mutating methods, flatMap, and chaining methods to transform data.
On this page
Most real JavaScript work is transforming lists of data: filtering products, totalling a cart, turning API results into HTML. Array methods that take a callback do this clearly and with less code than loops.
All examples in this lesson use this data:
const products = [
{ name: "Pen", price: 20, category: "stationery", inStock: true },
{ name: "Notebook", price: 60, category: "stationery", inStock: true },
{ name: "Headphones", price: 1500, category: "electronics", inStock: false },
{ name: "Charger", price: 450, category: "electronics", inStock: true },
];
console.log(products.length);4forEach: do something with each item#
const products = [
{ name: "Pen", price: 20 },
{ name: "Notebook", price: 60 },
];
products.forEach((p, index) => {
console.log(`${index + 1}. ${p.name}: ₹${p.price}`);
});1. Pen: ₹20
2. Notebook: ₹60The callback receives (item, index, array). forEach returns nothing and cannot be stopped early; use a for...of loop when you need break.
map: transform every item#
map returns a new array with the callback's result for each item:
const products = [
{ name: "Pen", price: 20 },
{ name: "Notebook", price: 60 },
{ name: "Charger", price: 450 },
];
const names = products.map((p) => p.name);
const withGst = products.map((p) => ({ ...p, price: Math.round(p.price * 1.18) }));
console.log(names);
console.log(withGst);[ 'Pen', 'Notebook', 'Charger' ]
[
{ name: 'Pen', price: 24 },
{ name: 'Notebook', price: 71 },
{ name: 'Charger', price: 531 }
]The new array always has the same length as the original. The original is not changed.
filter: keep some items#
filter returns a new array with only the items for which the callback returns a truthy value:
const products = [
{ name: "Pen", price: 20, inStock: true },
{ name: "Headphones", price: 1500, inStock: false },
{ name: "Charger", price: 450, inStock: true },
];
const available = products.filter((p) => p.inStock);
const affordable = products.filter((p) => p.price < 500 && p.inStock);
console.log(available.map((p) => p.name));
console.log(affordable.length);[ 'Pen', 'Charger' ]
2reduce: combine into one value#
reduce walks through the array carrying an accumulator, and returns its final value:
const cart = [
{ name: "Pen", price: 20, qty: 3 },
{ name: "Notebook", price: 60, qty: 2 },
];
const total = cart.reduce((sum, item) => sum + item.price * item.qty, 0);
console.log(total);180- The callback receives
(accumulator, item)and returns the new accumulator. - The second argument (
0) is the starting value. Always provide it.
reduce can build any result, such as grouping items into an object:
const products = [
{ name: "Pen", category: "stationery" },
{ name: "Charger", category: "electronics" },
{ name: "Notebook", category: "stationery" },
];
const byCategory = products.reduce((groups, p) => {
(groups[p.category] ??= []).push(p.name);
return groups;
}, {});
console.log(byCategory);{ stationery: [ 'Pen', 'Notebook' ], electronics: [ 'Charger' ] }Newer JavaScript also has Object.groupBy(products, (p) => p.category), which does this grouping directly.
find and findIndex#
Return the first matching item (or its index), and stop searching:
const products = [
{ name: "Pen", price: 20 },
{ name: "Charger", price: 450 },
{ name: "Cable", price: 300 },
];
console.log(products.find((p) => p.price > 100));
console.log(products.findIndex((p) => p.name === "Cable"));
console.log(products.find((p) => p.price > 5000));{ name: 'Charger', price: 450 }
2
undefinedfindLast and findLastIndex search from the end.
some and every#
const marks = [72, 95, 58, 88];
console.log(marks.some((m) => m < 60));
console.log(marks.every((m) => m >= 40));true
truesome: is at least one item a match?every: are all items a match?
sort#
sort sorts the array in place. Without a compare function, it sorts items as strings, which breaks numbers:
const numbers = [10, 1, 25, 3];
console.log([...numbers].sort());
console.log([...numbers].sort((a, b) => a - b));
console.log([...numbers].sort((a, b) => b - a));[ 1, 10, 25, 3 ]
[ 1, 3, 10, 25 ]
[ 25, 10, 3, 1 ]The compare function returns a negative number if a should come first, positive if b should, and 0 if they are equal. To sort objects:
const people = [
{ name: "Ravi", age: 31 },
{ name: "Asha", age: 25 },
{ name: "Meera", age: 28 },
];
console.log(people.toSorted((a, b) => a.age - b.age).map((p) => p.name));
console.log(people.toSorted((a, b) => a.name.localeCompare(b.name)).map((p) => p.name));[ 'Asha', 'Meera', 'Ravi' ]
[ 'Asha', 'Meera', 'Ravi' ]Mutating and non-mutating methods#
Some methods change the original array; others return a new one:
The to... versions and with were added in ES2023 and work in all current browsers and Node.js. Not changing the original is safer, especially in frameworks like React that compare old and new data.
Chaining#
Because map and filter return arrays, you can chain them into a pipeline:
const products = [
{ name: "Pen", price: 20, inStock: true },
{ name: "Notebook", price: 60, inStock: true },
{ name: "Headphones", price: 1500, inStock: false },
{ name: "Charger", price: 450, inStock: true },
];
const summary = products
.filter((p) => p.inStock)
.toSorted((a, b) => b.price - a.price)
.map((p) => `${p.name} (₹${p.price})`)
.join(", ");
console.log(summary);Charger (₹450), Notebook (₹60), Pen (₹20)Read it top to bottom: keep in-stock items, sort by price (highest first), format each, join into one string.
Practice#
Practice exercise
Given const orders = [{ id: 1, amount: 250, status: "paid" }, { id: 2, amount: 900, status: "pending" }, { id: 3, amount: 1200, status: "paid" }, { id: 4, amount: 80, status: "paid" }], print: the ids of paid orders, the total amount of paid orders, whether any order is over 1000, and the paid orders' amounts sorted from largest to smallest.
Show solution
const orders = [
{ id: 1, amount: 250, status: "paid" },
{ id: 2, amount: 900, status: "pending" },
{ id: 3, amount: 1200, status: "paid" },
{ id: 4, amount: 80, status: "paid" },
];
const paid = orders.filter((o) => o.status === "paid");
console.log(paid.map((o) => o.id));
console.log(paid.reduce((sum, o) => sum + o.amount, 0));
console.log(orders.some((o) => o.amount > 1000));
console.log(paid.map((o) => o.amount).toSorted((a, b) => b - a));[ 1, 3, 4 ]
1530
true
[ 1200, 250, 80 ]Key takeaway#
Finished this lesson?