JavaScript Arrays for Interviews: map/filter/reduce + Time Complexity

A deep, interview-ready guide to JavaScript arrays: core methods, common patterns, time/space complexity, mutation pitfalls, and practical questions with solutions.

F

Frontend Interview Team

February 08, 2026

~22 min
JavaScript Arrays for Interviews: map/filter/reduce + Time Complexity

Arrays look simple, but interviews use them to test:

  • fundamentals (mutation vs immutability)
  • algorithmic thinking
  • time complexity
  • ability to write clean transformations

This guide focuses on the array skills that appear most often in frontend interviews.

30‑second interview answer

For array transformations, prefer non-mutating methods like map, filter, and reduce. Know which methods mutate (push, sort) and be able to talk about complexity: most iterations are O(n), but nested loops and repeated find can become O(n²). In interviews, clarity + correct complexity beats cleverness.

Key points

  • Know mutating vs non-mutating methods.
  • Most array transforms are O(n).
  • Avoid repeated linear scans inside loops.
  • Prefer reduce when you’re building a single result.

1) Arrays are ordered lists (but not “vectors” in your head)

In JS, arrays are objects with special behavior.

Important implications:

  • arrays can be sparse (arr[100] = 'x') and have “holes”
  • performance can degrade if you treat them like hash maps

For interviews, assume arrays are contiguous unless the question is about sparsity.


2) Mutation vs non-mutation (very important)

Mutating methods (change original)

  • push, pop, shift, unshift
  • splice, sort, reverse

Non-mutating methods (return new)

  • map, filter, slice, concat
  • flat, flatMap

Interview tip: If you’re in a React codebase, avoid mutation unless you’re careful.


3) Time complexity cheat sheet (practical)

Let n = array.length.

  • Access by index arr[i]O(1)
  • push / pop (end) → O(1) amortized
  • shift / unshift (front) → O(n) (reindexing)
  • map, filter, reduce, forEachO(n)
  • includes, indexOf, find, some, everyO(n)
  • sort → typically O(n log n)

If you need fast membership checks, use a Set.


4) map: transform each element

const nums = [1, 2, 3];
const doubled = nums.map((x) => x * 2);
// [2,4,6]

Rules:

  • map returns a new array of same length
  • don’t use map when you want side effects

5) filter: keep items that match a condition

const users = [{ active: true }, { active: false }];
const active = users.filter((u) => u.active);

Rule:

  • filter may return smaller array

6) reduce: fold into a single value (or object)

Example A: sum

const sum = [1,2,3].reduce((acc, x) => acc + x, 0);

Example B: group by (common interview pattern)

const byTag = posts.reduce((acc, post) => {
  for (const tag of post.tags) {
    (acc[tag] ||= []).push(post);
  }
  return acc;
}, {});

Interview advice:

  • always provide initial value in reduce unless you’re 100% sure
  • avoid reduce when map+filter is clearer

7) Avoid shift() in loops

This is a common perf footgun.

Bad:

while (arr.length) {
  const x = arr.shift(); // O(n) each
}

Better:

  • use an index pointer
  • or treat it as a queue with a head index
let head = 0;
while (head < arr.length) {
  const x = arr[head++];
}

8) Common interview problems

Problem 1: Remove duplicates

const unique = [...new Set(arr)];

Time: O(n) average, space: O(n)

Problem 2: Two-sum (classic)

Given nums and target, return indices of two numbers that add to target.

function twoSum(nums, target) {
  const seen = new Map();
  for (let i = 0; i < nums.length; i++) {
    const x = nums[i];
    const need = target - x;
    if (seen.has(need)) return [seen.get(need), i];
    seen.set(x, i);
  }
  return null;
}

Problem 3: Flatten one level

const flat = arr.flat();

Or manual:

const flat = arr.reduce((acc, x) => acc.concat(x), []);

9) Pitfalls interviewers love

A) sort() sorts strings by default

[10, 2, 30].sort(); // [10,2,30] (wrong expectation)

Fix:

[10,2,30].sort((a,b) => a-b); // [2,10,30]

B) includes(NaN) works, indexOf(NaN) doesn’t

[NaN].includes(NaN) // true
[NaN].indexOf(NaN)  // -1

C) slice vs splice

  • slice is non-mutating
  • splice mutates

10) When to prefer loops over map/filter

In interviews, clarity matters. Performance matters too.

If you need:

  • early exit
  • complex branching
  • building multiple outputs in one pass

A for loop can be the cleanest.


Summary checklist

  • I can list mutating methods.
  • I know shift/unshift are O(n).
  • I can explain when reduce is appropriate.
  • I avoid O(n²) patterns with repeated find.

Summary

  • Know mutation vs non-mutation.
  • Know practical complexities (shift/unshift are O(n)).
  • Use map/filter/reduce for readable transformations.
  • Use Set/Map when you need fast lookup.
  • Watch for sort and NaN pitfalls.