Difference between map, filter, and reduce

Intermediate12 min interview
Skills tested:
map, filter, reduce return value and signatureChaining array methods correctlyUsing reduce for non-obvious transformations like grouping and flatteningPerformance implications of chaining multiple array passesChoosing between forEach and map when side effects are involved

Advertisement

🧩 Scenario

In a real codebase, you will use these three methods for transforming API data before rendering, computing aggregate values like totals and averages, filtering lists based on user input, and building lookup structures from arrays. They appear in every React component that renders a list, in every data processing pipeline, and in every utility that works with collections.

Architecture Walkthrough

map: Transform Every Element

map creates a new array by applying a callback to every element of the source array. The callback receives the current element, its index, and the original array. Whatever the callback returns becomes the corresponding element in the new array. The original array is not modified.

If the callback does not explicitly return a value, it implicitly returns undefined, so the resulting array will be filled with undefined. This is one of the most common beginner bugs with map. A concise arrow function without curly braces returns implicitly, but adding braces requires an explicit return.

filter: Select Matching Elements

filter creates a new array containing only elements for which the callback returns a truthy value. Elements for which the callback returns a falsy value are excluded. The original array is not modified and the length of the result may be shorter.

filter is useful when combined with map: filtering first reduces the array size before the transformation step, which can improve performance if the transformation is expensive. However, if the filter condition depends on the transformed value, the order must be reversed.

reduce: Accumulate to a Single Value

reduce is the most general of the three methods. It applies a callback to an accumulator and each element in turn, returning a single final value. The accumulator starts as the second argument to reduce (the initial value). The callback receives the current accumulator, the current element, the index, and the original array.

reduce can produce any output: a number, a string, an object, or even a new array. This makes it powerful enough to implement both map and filter internally. In practice, use reduce for aggregations (sum, count, average), grouping (an array of items into an object keyed by category), and any transformation that produces a different shape than the input.


Key Code Explained

const orders = [
  { id: 1, status: 'shipped', total: 120 },
  { id: 2, status: 'pending', total: 85 },
  { id: 3, status: 'shipped', total: 200 },
  { id: 4, status: 'pending', total: 45 },
];

// map: transform to a new shape
const totals = orders.map((o) => o.total);
// [120, 85, 200, 45]

// filter: select by condition
const shipped = orders.filter((o) => o.status === 'shipped');
// [{ id: 1, ... }, { id: 3, ... }]

// reduce: sum all totals
const grandTotal = orders.reduce((sum, o) => sum + o.total, 0);
// 450

// reduce: group by status (a non-obvious but practical use)
const grouped = orders.reduce((acc, order) => {
  const key = order.status;
  if (!acc[key]) acc[key] = [];
  acc[key].push(order);
  return acc;
}, {});
// { shipped: [order1, order3], pending: [order2, order4] }

// Chained: sum of totals for shipped orders only
const shippedTotal = orders
  .filter((o) => o.status === 'shipped')
  .reduce((sum, o) => sum + o.total, 0);
// 320

// Common mistake: missing return in map with curly braces
const broken = orders.map((o) => {
  o.total * 1.1; // no return — produces [undefined, undefined, ...]
});

const correct = orders.map((o) => ({
  ...o,
  total: o.total * 1.1,
}));

The grouping reduce example is worth memorizing for interviews because it shows reduce being used to produce an object from an array, not just a scalar value. This pattern comes up in data processing frequently.


Tradeoffs

MethodReturnsUse when
mapNew array, same lengthYou need to transform every element into a new value
filterNew array, shorter or equal lengthYou need to select a subset of elements
reduceSingle value of any typeYou need to aggregate, group, or fold an array into one result
forEachundefinedYou only need side effects and do not care about a return value

What Interviewers Actually Check

  • Whether you can explain each method's return type and purpose without confusing them
  • Whether you know map without a return produces undefined values
  • Whether you can use reduce to produce an object, not just a scalar
  • Whether you know the performance cost of chaining multiple passes and when it matters
  • Whether you can distinguish when forEach is more appropriate than map

Follow-Up Questions

  1. How would you implement Array.prototype.map yourself using reduce?
  2. What is flatMap and when does it avoid the need for chaining map followed by flat?
  3. If you need to process a very large array (millions of items) with filter and map, what performance concern would you raise about chaining?
  4. How does React's rendering of list items with .map() require unique key props, and what goes wrong without them?
  5. A code review shows .forEach() being used to build a new array by pushing into an outer variable. What would you suggest instead?

Common Candidate Mistakes

  • Forgetting to return a value from a map callback written with curly braces, producing an array of undefined
  • Using map when only side effects are needed (mutation, logging), when forEach is the semantically correct choice
  • Not providing an initial value to reduce, causing it to use the first element as the accumulator and skip it as input
  • Chaining filter before map when map first would have reduced unnecessary work
  • Mutating properties of the original array's elements inside a map callback instead of returning a new object

Interview Readiness Checklist

Before you leave this question, make sure you can answer:

  • Can you explain what each method returns without looking it up?
  • Can you write a reduce that groups an array of objects by a key into an object of arrays?
  • Can you explain why forgetting to return inside a map callback produces an array of undefined?
  • Can you chain filter, map, and reduce in one expression to solve a multi-step data problem?
  • Can you explain when to use forEach instead of map and why the distinction matters?

Summary

map, filter, and reduce are the core higher-order functions for working with arrays without mutation. map transforms every element into a new value and returns an array of the same length. filter selects elements that pass a test and returns a potentially shorter array. reduce folds an entire array into a single output value of any type.

In practice, reduce is the most powerful of the three because it can replicate the behavior of both map and filter. However, for transforming and selecting, map and filter are more readable and should be preferred. reduce shines for aggregation and grouping tasks where the output shape is fundamentally different from the input.

The most common mistakes on these methods are missing return statements in map, using map when forEach is correct, and not providing a reduce initial value. Knowing the grouping pattern for reduce and the performance implications of chaining multiple passes sets a candidate apart from those who only know the basic sum example.

Related Videos
Watch these videos to learn more about this topic
Frequently Asked Questions

Which one modifies the original array?

None of them. They all return new arrays or values without mutating the original.

Advertisement


Stay Updated

Get the latest frontend challenges, interview questions and tutorials delivered to your inbox.

Advertisement