learn
JavaScript

Arrays and array methods

map, filter, reduce, find, the sort pitfall, and mutating versus new.

Array methods encode intent: map transforms, filter selects, reduce folds. Interviewers ask this to hear you pick by return shape — and to catch the in-place sort corrupting shared state.

Real-life situation

A dashboard lists orders over $50 with their revenue total. filter picks the big orders, map pulls their totals, reduce folds one revenue number — three readable steps, no manual loop, original array untouched. Then a sort for the leaderboard mutates the shared ranks array, and every other widget shows the new order too.

Visual

Array methods
BrowserAPIRealtimeCacheDatabaseShareddurableephemeral

Try it

Dashboard pipeline
javascriptTab moves to the next control
const orders = [
{ id: 1, total: 30 },
{ id: 2, total: 120 },
{ id: 3, total: 80 },
];
const big = orders.filter(function (o) {
return o.total >= 50;
});
console.log(big.length);
const sums = big.map(function (o) {
return o.total;
});
console.log(sums[0]);
console.log(sums[1]);
const revenue = sums.reduce(function (sum, n) {
return sum + n;
}, 0);
console.log(revenue);
const ranks = [10, 9, 80];
console.log(ranks.sort()[0]);
console.log(
ranks.slice().sort(function (a, b) {
  return a - b;
})[0],
);
Press Run to see the output.
Expected output
2
120
80
200
10
9
Runner helpers

sleep(ms) waits; fakeFetch(url) returns deterministic sample data. Console code runs in a worker with a 5-second limit.

Try changing the filter to o.total > 100 and predict the revenue first. Then sort a copy with toSorted and compare. Time yourself rewriting the pipeline with a single reduce, then compare readability honestly.

Mutating versus new

Chain the non-mutating ones (map, filter, slice, toSorted) for shared data. Reserve sort, splice and reverse for local scratch arrays nobody else sees.

Default sort — guess first, then reveal.

predict.js
const bids = [10, 9, 80];
console.log(bids.sort()[0]);

Interview questions

What do map, filter and reduce each return?basic

map returns a new array with the callback applied to every item — same length, transformed values. filter returns a new array with only the items whose callback returned truthy — shorter or equal. reduce returns ONE value of your choosing (a total, an object, anything) built by folding items left to right with an accumulator. All three leave the original untouched; that non-mutation is half the reason they exist.

Interviewers also ask

  • When would you pick reduce over a loop?
Which array methods mutate and which return new arrays?basic

Mutating: push, pop, shift, unshift, splice, sort, reverse, fill. Non-mutating: map, filter, reduce, find, slice, concat, toSorted, toSpliced, spread. The classic bug is sorting shared state in place. Modern style chains the non-mutating ones and reserves mutation for local scratch arrays nobody else can see.

Interviewers also ask

  • What is the non-mutating version of sort?
What is the sort pitfall every interviewer mentions?intermediate

Default sort compares as STRINGS: [10, 9, 80].sort() gives [10, 80, 9] because "10" < "80" < "9" lexicographically. Always pass a comparator for numbers: sort((a, b) => a - b). Second half of the pitfall: sort mutates in place, so sort a copy ([...items].sort(...) or toSorted) when the original must survive.

Interviewers also ask

  • How do you sort without mutating?
What is the difference between find, filter and includes?basic

find returns the FIRST matching item (or undefined) — use it when you want the thing itself. filter returns ALL matches as an array — use it for lists. includes answers a yes/no question about a VALUE (list. includes(id)), not a condition. Picking the right one signals you think in return shapes, which is exactly what the question tests.

Interviewers also ask

  • How do you check a condition on every item?
How do you flatten nested arrays, and how deep can you go?intermediate

One level: flat() or flatMap() (map-then-flatten in a single pass — ideal for "orders to items" transforms). Arbitrary depth: flat(Infinity) or a recursive reduce. flatMap deserves special mention because it fuses two passes into one and reads cleanly. Depth beyond two usually means the data shape wants rethinking, not deeper flattening.

Interviewers also ask

  • What does flatMap do that map plus flat does not?
How do you remove duplicates from an array?basic

[...new Set(items)] — Set keeps first-seen order and drops repeats in one readable line. It compares by reference for objects, so identical LOOKING objects survive; dedupe those by a key (Map by id) instead. For the keyed case, build a Map and take its values — same one-pass idea, explicit key.

Interviewers also ask

  • Why doesn't Set dedupe identical objects?
Why is reduce powerful enough to replace map and filter?intermediate

Because reduce exposes the accumulator, and the accumulator can BE the output array: push transformed items to mimic map, push conditionally to mimic filter. Interviewers ask this to check you see past the "totals only" stereotype. In real code still prefer map/filter — they declare intent where reduce makes readers reconstruct it.

Interviewers also ask

  • When is reduce the wrong tool despite working?
How do you group items by a key?intermediate

With Object.groupBy(items, item => item.key) in modern engines, or a reduce into an object of arrays everywhere else. Group-then-render (orders by status, tasks by day) is a daily UI shape, so name it confidently. Watch the edge: items missing the key land under "undefined" — decide whether that bucket is a bug or a feature.

Interviewers also ask

  • How would you do it without Object.groupBy?
What does slice do that splice does not?basic

slice copies a section into a NEW array and never touches the original — safe to use anywhere. splice edits the array IN PLACE (remove, insert, replace) and returns the removed items. The names differ by one letter and the behavior is opposite, which is precisely why interviewers pair them. Default to slice; reach for splice only for deliberate in-place edits.

Interviewers also ask

  • How do you remove an item without mutating?
How do you turn an array into an object keyed by id?intermediate

Object.fromEntries(items.map(i => [i.id, i])) for the declarative version, or a reduce accumulating into {}. It is the standard normalize step before rendering keyed lists or caching by id. Guard the edge your interviewer will probe: duplicate ids silently overwrite — decide last-wins versus throw, and say which you chose.

Interviewers also ask

  • What breaks with duplicate ids?

Key takeaways

  • map/filter return new arrays; reduce folds to one value.
  • Default sort is lexicographic and in place — pass a comparator, copy first.
  • Pick methods by return shape: transform, select, find or fold.

References

Last verified: 2026-10-12.

On this page