Which array method should you use?
By FrontendPro Editorial Team Updated 9/26/2026
Answer
Pick by what you want back.
| Want | Method |
|---|---|
| A new array, same length | map |
| A shorter array | filter |
| One value from many | reduce |
| The first matching item | find |
| Its position | findIndex |
| Yes/no, at least one | some |
| Yes/no, all of them | every |
| Just side effects | forEach |
Need break or await | for...of |
const active = users.filter((u) => u.active);
const names = active.map((u) => u.name);
const total = orders.reduce((sum, o) => sum + o.price, 0);
const admin = users.find((u) => u.role === "admin");
Use the method that states the intent
filter().map() reads as "keep these, then transform" — a for loop with a conditional push does the same thing but the reader has to infer it. Chaining creates an intermediate array, which is irrelevant for normal sizes and only worth avoiding for very large ones.
Two things forEach cannot do
It ignores await, so the surrounding code continues before the work finishes:
items.forEach(async (x) => await save(x)); // does not wait
for (const x of items) await save(x); // sequential
await Promise.all(items.map(save)); // parallel
And you cannot break out of it — return only skips the current item. Use for...of, or some/find when the goal is early exit.
Mutating vs copying
sort and reverse change the array in place, which surprises callers. Their copying versions toSorted and toReversed avoid that:
const sorted = [...items].sort(byName); // older pattern
const sorted = items.toSorted(byName); // modern
One detail
Array methods skip holes in sparse arrays, while for...of visits them as undefined — rarely relevant, but it explains occasional surprising results.
