MediumCoding

How do you flatten a nested array in JavaScript without using flat()?

Technology:
JavaScript,
Algorithms,
Data Structures
Experience:
Junior,
Mid-level

Quick answer

Recursively walk the array: when an element is an array, flatten it and append the result; otherwise append the element. An iterative version uses an explicit stack to avoid recursion limits.

Problem

Write a function that takes an array that may contain nested arrays to any depth and returns a new, single-level array with all the values in their original order.

Input

[1, [2, [3, [4]], 5]]

Output

[1, 2, 3, 4, 5]

Constraints

  • Do not use Array.prototype.flat
  • Preserve the original order

Example

The nested values 2, 3, 4 and 5 are lifted to the top level in the order they appear.

Solution

javascript
function flatten(arr) {
  const result = [];
  for (const item of arr) {
    if (Array.isArray(item)) {
      result.push(...flatten(item));
    } else {
      result.push(item);
    }
  }
  return result;
}

flatten([1, [2, [3, [4]], 5]]); // [1, 2, 3, 4, 5]

Loop through each item of the input array.

If the item is an array, flatten it recursively and push its values.

Otherwise push the item itself.

Return the collected result.

Time complexity

O(n), where n is the total number of values across all nesting levels.

Space complexity

O(n) for the output plus O(d) call-stack depth, where d is the maximum nesting depth.

Alternative approach

An iterative version uses a stack, which avoids recursion limits for very deep arrays. Pop from the end, push nested arrays back, and reverse at the end to restore the order.

javascript
function flattenIterative(arr) {
  const stack = [...arr];
  const result = [];
  while (stack.length) {
    const item = stack.pop();
    if (Array.isArray(item)) stack.push(...item);
    else result.push(item);
  }
  return result.reverse();
}

Discussion

In real code arr.flat(Infinity) does this, and you should say so. Interviewers ask you to write it yourself to see recursion, Array.isArray and how you reason about depth.

The recursive solution mirrors the structure of the data and is easy to explain. For very deep nesting it can hit the call-stack limit, so mentioning an iterative stack-based version is a good follow-up.

Common mistakes

  • Using typeof item === "object" to detect arrays, which also matches objects and null.
  • Mutating the input array.

Follow-up questions

  • How would you flatten only to a given depth?
  • JavaScriptEasyCoding

    How do you check if a string is a palindrome in JavaScript?

    Normalise the string (lower case, remove non-alphanumeric characters), then compare characters from both ends moving inward with two pointers. This is O(n) time and O(1) extra space beyond the normalised copy.

    Intern · Junior · Coding Problems
  • JavaScriptEasyCoding

    How do you solve the Two Sum problem in JavaScript?

    Walk through the array once while storing each number’s index in a hash map; for every number, check whether target minus that number is already in the map. This runs in O(n) time and O(n) space.

    Junior · Mid-level · Coding Problems
  • JavaScriptEasy

    What is hoisting in JavaScript?

    Hoisting is JavaScript moving declarations to the top of their scope during compilation, so functions and var variables can be referenced before the line where they are written.

    Intern · Junior · Functions & Scope
  • JavaScriptMedium

    What is a closure in JavaScript and why is it useful?

    A closure is a function that keeps access to the variables of the scope where it was created, even after that outer function has finished running.

    Junior · Mid-level · Functions & Scope