Array Flatten in JavaScript

If you work with JavaScript long enough, eventually, you will receive a data structure from an API that looks less like a neat list and more like a set of Russian nesting dolls. You reach for an item, only to find it trapped inside an array, which is inside another array, which is inside yet another array.
Dealing with deeply nested data is a rite of passage for JavaScript developers. To process, filter, or render that data effectively, you usually need to transform it into a single, flat list.
Let's explore what nested arrays are, why we flatten them, and the step-by-step problem-solving thinking required to tackle this common challenge—especially in a technical interview.
What Exactly is a Nested Array?
Think of a standard array as a single box with dividers. You can look inside and immediately see every item in its designated slot.
A nested array (or multidimensional array) is a box where some of the slots contain more boxes.
Here is a visual representation of how that looks in code:
// A standard, flat array (1D)
const flatArray = [1, 2, 3, 4, 5];
// A nested array (2D) - Box inside a box
const slightlyNested = [1, 2, [3, 4], 5];
// A deeply nested array (3D+) - Boxes inside boxes inside boxes
const deeplyNested = [1, [2, [3, [4]], 5]];
Why Flattening Arrays is Useful
Why not just leave the data in its nested state? In the real world, nested arrays create roadblocks.
Data Processing: If you need to map over user IDs, calculate a total sum, or filter out specific values, writing nested
forloops or multiple.map()calls becomes messy and hard to read.UI Rendering: Frameworks like React expect flat lists when mapping data to UI components. If you have a nested array of categories and sub-categories, you usually need to flatten them to render a clean dropdown menu or a continuous list.
Data Normalization: Bringing disparate data structures into a single, uniform format makes the rest of your application logic much simpler.
The Concept: Step-by-Step Flattening
The core concept of flattening is simple: Extract the items from inner arrays and place them directly into the parent array.
If we have [1, [2, 3]], flattening it means taking 2 and 3 out of their inner brackets, resulting in [1, 2, 3].
When approaching this problem, the thought process should always be:
Look at each item in the array.
Is this item a standard value (like a number or string)? If yes, keep it.
Is this item another array? If yes, extract its contents.
Repeat until no arrays are left inside.
3 Approaches to Flattening Arrays
Let's look at how to actually implement this, starting with the easiest method and moving to the custom solutions you will need for interviews.
1. The Modern Built-in: Array.prototype.flat()
Introduced in ES2019, JavaScript now gives us a built-in method to handle this out of the box.
const nested = [1, [2, [3, [4]]]];
// By default, .flat() only goes one level deep
console.log(nested.flat());
// Result: [1, 2, [3, [4]]]
// You can pass a depth argument.
console.log(nested.flat(2));
// Result: [1, 2, 3, [4]]
// Pro-tip: Pass Infinity to flatten completely, no matter how deep!
console.log(nested.flat(Infinity));
// Result: [1, 2, 3, 4]
Note: While .flat(Infinity) is incredibly useful for production code, if you are in a technical interview, the interviewer will almost certainly ask you to implement this behavior from scratch.
2. The Functional Approach: reduce and concat
If you only need to flatten an array by one level, combining .reduce() with .concat() is a clean, functional approach.
const nested = [1, [2, 3], [4, 5]];
const flatOneLevel = nested.reduce((accumulator, currentValue) => {
return accumulator.concat(currentValue);
}, []);
console.log(flatOneLevel); // Result: [1, 2, 3, 4, 5]
How it works: We start with an empty array [] (the accumulator). We loop through our nested array. If currentValue is a number (like 1), concat adds it. If currentValue is an array (like [2, 3]), concat naturally unpacks it and adds the items.
3. The Interview Classic: Deep Flatten via Recursion
How do we handle unpredictable, infinite depth without the built-in .flat()? We use recursion—a function that calls itself.
This is the ultimate test of your problem-solving skills. Here is the mental model:
We will loop through the array.
If we see a normal value, we push it to our result.
If we see an array, we pause, and pass that array back into our flattening function to be processed.
function deepFlatten(arr) { let result = [];
for (let i = 0; i < arr.length; i++) { const currentItem = arr[i];
// Check if the current item is an array
if (Array.isArray(currentItem)) {
// If it IS an array, recursively call deepFlatten on it
// and merge the returned flat array into our result
result = result.concat(deepFlatten(currentItem));
} else {
// If it is NOT an array, just push the value
result.push(currentItem);
}
}
return result; }
const crazyNested = [1, [2, [3, [4, 5]]], 6]; console.log(deepFlatten(crazyNested)); // Result: [1, 2, 3, 4, 5, 6]



