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
Try it
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],
);Expected output
2 120 80 200 10 9
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.
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/filterreturn new arrays;reducefolds to one value.- Default
sortis 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.
Runner helpers
sleep(ms)waits;fakeFetch(url)returns deterministic sample data. Console code runs in a worker with a 5-second limit.