DEV Community

Cover image for Array Flatten in JavaScript
SATYA SOOTAR
SATYA SOOTAR

Posted on

Array Flatten in JavaScript

Hello readers đź‘‹, welcome to the 12th blog of this JavaScript series!

This time we’re diving into a topic that looks simple but pops up everywhere, from real projects to technical interviews. We’re talking about Array Flattening in JavaScript.

In real life, imagine you have a set of nested gift boxes. A big box contains smaller boxes, and inside those, even more boxes. If you want to see all the gifts at once, you open each box and lay everything out flat on the table. That’s exactly what we do with nested arrays, we flatten them into a single-level array.

Let’s break it down step by step.

What are nested arrays?

A nested array is simply an array that contains other arrays as its elements. It can go multiple levels deep - arrays inside arrays inside arrays.

In JavaScript, it looks like this:

const nested = [1, [2, [3, 4], 5], 6];
Enter fullscreen mode Exit fullscreen mode

If you visualize the structure, it’s like a tree where some branches have more branches before reaching the leaves (the actual values).

Level 0:  [1, [ … ], 6]
Level 1:       [2, [ … ], 5]
Level 2:            [3, 4]
Enter fullscreen mode Exit fullscreen mode

This kind of data is extremely common when working with APIs, file systems, comment threads, or any hierarchical data.

Why do we need to flatten arrays?

In many situations, you don’t care about the nesting - you just need a plain list of all items. Here’s why flattening is useful:

  • Rendering lists - frameworks like React expect flat arrays when you map over data.
  • Data processing - operations like filtering, sorting, or finding things become easier on a flat array.
  • API responses - sometimes an endpoint gives you a nested structure, but you only need the inner values.
  • Problem solving - many coding challenges begin with normalising a nested structure.

Whether you’re working on a to-do app or preparing for an interview, understanding array flattening will save you a lot of headaches.

Concept of flattening arrays

Flattening means taking a deeply nested array and converting it into a single-level array, preserving the order of elements.

Visually, here’s the transformation:

Before flatten (deeply nested):
[
  1,
  [2, [3, 4], 5],
  6
]

After full flatten (depth = Infinity):
[1, 2, 3, 4, 5, 6]
Enter fullscreen mode Exit fullscreen mode

You can also flatten only up to a certain depth:

Original:        [1, [2, [3, 4], 5], 6]
Flatten depth=1: [1, 2, [3, 4], 5, 6]
Flatten depth=2: [1, 2, 3, 4, 5, 6]   // same as Infinity in this case
Enter fullscreen mode Exit fullscreen mode

So the depth parameter controls how many levels of nesting are removed.

Different approaches to flatten arrays

There are several ways to get a flat array. I’ll cover the most practical ones - from the modern built-in method to the manual logic interviewers love.

1. Using Array.prototype.flat()

ES2019 introduced the flat() method, and it’s the go-to in daily work.

const arr = [1, [2, [3, 4], 5], 6];

// flatten one level
console.log(arr.flat());        // [1, 2, [3, 4], 5, 6]

// flatten completely
console.log(arr.flat(Infinity)); // [1, 2, 3, 4, 5, 6]
Enter fullscreen mode Exit fullscreen mode

The default depth is 1. Pass Infinity if you don’t know (or don’t care about) the maximum depth and want everything flattened.

When to use: in production code when you just need a quick, clean solution.

2. Recursive approach (custom flat function)

This is a classic interview favourite. The idea is to loop through the array and check each element:

  • If it’s an array, recursively flatten it.
  • If it’s not an array, push it to the result.
function flatten(arr) {
  const result = [];

  for (const item of arr) {
    if (Array.isArray(item)) {
      // recursively flatten and push all its elements
      result.push(...flatten(item));
    } else {
      result.push(item);
    }
  }

  return result;
}

console.log(flatten([1, [2, [3, 4], 5], 6])); // [1, 2, 3, 4, 5, 6]
Enter fullscreen mode Exit fullscreen mode

Problem-solving thinking:

  • Base case: the current element is not an array → add it.
  • Recursive case: element is array → call flatten again and spread the returned array into the result.
  • This will keep diving deeper until all levels are opened.

3. Using reduce() and concat()

For one-level flattening, you can combine reduce and concat:

const arr = [1, [2, 3], [4, 5]];

const flat = arr.reduce((acc, val) => acc.concat(val), []);
console.log(flat); // [1, 2, 3, 4, 5]
Enter fullscreen mode Exit fullscreen mode

You can make it recursive for deep flattening, but it becomes a bit less readable:

function deepFlatten(arr) {
  return arr.reduce(
    (acc, val) =>
      Array.isArray(val) ? acc.concat(deepFlatten(val)) : acc.concat(val),
    []
  );
}
Enter fullscreen mode Exit fullscreen mode

Though it works, I personally find the plain for-of recursive version easier to explain and debug.

4. Iterative approach using a stack (no recursion)

Recursion is elegant, but deep arrays can cause stack overflow. In interviews, they sometimes ask: “Can you do it without recursion?”

Yes - using a stack.

function flatten(arr) {
  const stack = [...arr];
  const result = [];

  while (stack.length) {
    const next = stack.pop();
    if (Array.isArray(next)) {
      // push back the elements so we process them later
      stack.push(...next);
    } else {
      // we use unshift to maintain original order
      result.unshift(next);
    }
  }

  return result;
}
Enter fullscreen mode Exit fullscreen mode

How it works:

  • Start with a copy of the original array as the stack.
  • Keep popping the last element.
  • If it’s an array, spread its contents back onto the stack (they will be processed eventually).
  • If it’s a value, add it to the front of the result (so the order stays correct).
  • Continue until the stack is empty.

This approach gives you complete control and doesn’t rely on recursion depth limits.

5. Using flatMap()

flatMap() first maps each element using a callback, then flattens the result by exactly one level. It’s perfect when you want to transform and flatten at the same time.

const arr = [1, 2, 3];

const mapped = arr.flatMap(x => [x, x * 2]);
console.log(mapped); // [1, 2, 2, 4, 3, 6]
Enter fullscreen mode Exit fullscreen mode

Keep in mind, flatMap is not for deep flattening - it only goes one level.

Common interview scenarios

Array flattening is a go-to topic for assessing recursion and problem-solving skills. Here are typical questions and how I’d approach them.

Scenario 1: “Write a function that flattens an array of arbitrarily nested arrays.”

We already covered the recursive solution. Interviewers want to see that you:

  • Identify the recursive structure (array inside array).
  • Handle base case (non-array element).
  • Use spreading or result concatenation.
  • Handle edge cases (empty arrays, non-array inputs).

I’d present the for-of recursive version because it’s clean and easy to reason about.

Scenario 2: “Implement a function flat(arr, depth) that works like the built-in flat.”

Here you need to add a depth counter. When depth is 0, stop flattening.

function flat(arr, depth = 1) {
  const result = [];

  for (const item of arr) {
    if (Array.isArray(item) && depth > 0) {
      result.push(...flat(item, depth - 1));
    } else {
      result.push(item);
    }
  }

  return result;
}

// test
const arr = [1, [2, [3, 4], 5], 6];
console.log(flat(arr, 1)); // [1, 2, [3, 4], 5, 6]
console.log(flat(arr, 2)); // [1, 2, 3, 4, 5, 6]
Enter fullscreen mode Exit fullscreen mode

This shows you can extend the basic logic and respect the depth limit.

Scenario 3: “How would you handle a deeply nested array without recursion?”

That’s where the stack-based iterative method shines. It also shows you understand the potential limitations of recursion (call stack size). You can explain the stack approach and mention it trades recursion for manual stack management.

Quick reference table of methods

Method Flatten depth Use case
arr.flat(depth) depth (default 1) Everyday coding, quick flattening
Recursive function unlimited or custom depth Interviews, custom logic
reduce + concat 1 level (extendable) Functional style one‑level flatten
Stack (iterative) unlimited Deep nests without recursion
arr.flatMap(fn) exactly 1 level Mapping + flattening in one step

Conclusion

Array flattening is one of those fundamental JavaScript concepts that you’ll use constantly. The built‑in flat() method is great for quick jobs, but knowing the manual ways builds your recursive thinking and prepares you for the coding challenges that come your way.

Key takeaways:

  • Nested arrays are like boxes inside boxes.
  • Flattening brings all elements to the top level.
  • You can use flat(), recursion, stack, or flatMap depending on the need.
  • Depth control is essential for real‑world problems and interviews.
  • Problem‑solving thinking (base case, recursive case, handling order) is more important than memorising code.

Hope you liked this blog. If there’s any mistake or something I can improve, do tell me. You can find me on LinkedIn and X, I post more stuff there.

Top comments (0)