Array Iteration Methods

Array iteration methods take a callback and apply it to every element. map transforms, filter selects, reduce combines, find searches, and some/every test. Learning these replaces most hand-written loops with short, readable code.

forEach — do something with each item

JS foreach.js
const guests = ["Ana", "Ben", "Cleo"];

guests.forEach((name, index) => {
  console.log(`${index + 1}. ${name}`);
});
Output
1. Ana
2. Ben
3. Cleo

Every iteration method passes the callback up to three arguments: the item, its index, and the whole array. forEach always returns undefined and can't be stopped early with break — use a for…of loop if you need to stop.

map — transform every item

map builds a new array of the same length, containing whatever the callback returns for each item:

JS map.js
const prices = [10, 25, 40];
const labels = prices.map(p => `$${p.toFixed(2)}`);

const users = [{ first: "Ada", last: "Lovelace" }, { first: "Alan", last: "Turing" }];
const fullNames = users.map(u => `${u.first} ${u.last}`);

console.log(labels);
console.log(fullNames);
console.log(prices);
Output
[ '$10.00', '$25.00', '$40.00' ]
[ 'Ada Lovelace', 'Alan Turing' ]
[ 10, 25, 40 ]

filter — keep some items

filter returns a new array containing only items for which the callback returns a truthy value:

JS filter.js
const products = [
  { name: "Lamp", price: 30, inStock: true },
  { name: "Desk", price: 120, inStock: false },
  { name: "Chair", price: 75, inStock: true },
];

const available = products.filter(p => p.inStock);
const affordable = available.filter(p => p.price < 50);

console.log(available.map(p => p.name));
console.log(affordable.map(p => p.name));
Output
[ 'Lamp', 'Chair' ]
[ 'Lamp' ]

find, findIndex, findLast

JS find.js
const orders = [
  { id: 1, status: "shipped" },
  { id: 2, status: "pending" },
  { id: 3, status: "pending" },
];

console.log(orders.find(o => o.status === "pending"));
console.log(orders.findIndex(o => o.id === 3));
console.log(orders.findLast(o => o.status === "pending"));
console.log(orders.find(o => o.status === "lost"));
Output
{ id: 2, status: 'pending' }
2
{ id: 3, status: 'pending' }
undefined

find returns the first matching item and stops looking; filter returns all matches in an array. If nothing matches, find gives undefined and findIndex gives -1.

some and every

JS some-every.js
const ages = [19, 25, 17, 32];

console.log(ages.some(a => a < 18));
console.log(ages.every(a => a >= 18));
console.log([].every(a => a > 100));
Output
true
false
true

some: is at least one item a match? every: do all items match? Both stop as soon as the answer is known. Note that every on an empty array is true.

reduce — combine into one value

reduce walks through the array carrying an accumulator. The callback receives the accumulator and the current item and returns the new accumulator:

JS reduce.js
const cart = [
  { item: "pen", price: 2, qty: 3 },
  { item: "pad", price: 5, qty: 1 },
  { item: "ink", price: 8, qty: 2 },
];

const total = cart.reduce((sum, line) => sum + line.price * line.qty, 0);
console.log(total);

const byItem = cart.reduce((acc, line) => {
  acc[line.item] = line.qty;
  return acc;
}, {});
console.log(byItem);
Output
27
{ pen: 3, pad: 1, ink: 2 }

The second argument (0, {}) is the starting value. Always provide one — without it, reduce on an empty array throws an error.

Grouping with Object.groupBy

Grouping items by a key is so common that it's now built in:

JS group.js
const people = [
  { name: "Ann", team: "red" },
  { name: "Bo", team: "blue" },
  { name: "Cy", team: "red" },
];

const teams = Object.groupBy(people, p => p.team);
console.log(Object.keys(teams));
console.log(teams.red.map(p => p.name));
Output
[ 'red', 'blue' ]
[ 'Ann', 'Cy' ]

Chaining

Because map and filter return arrays, they chain naturally into readable data pipelines:

JS chain.js
const transactions = [
  { type: "sale", amount: 120 },
  { type: "refund", amount: 30 },
  { type: "sale", amount: 80 },
  { type: "sale", amount: 15 },
];

const bigSalesTotal = transactions
  .filter(t => t.type === "sale")
  .filter(t => t.amount >= 50)
  .map(t => t.amount)
  .reduce((sum, n) => sum + n, 0);

console.log(bigSalesTotal);
Output
200

Which method do I need?

I want…UseReturns
A transformed copy of every itemmapArray, same length
Only the items that matchfilterArray, maybe shorter
The first matchfind / findIndexItem / index
Yes/no about the itemssome / everyBoolean
A single combined valuereduceAnything
Side effects only (logging, DOM updates)forEachundefined

Try it yourself

Try it yourself
Console output