Array Flatten in JavaScript: A Comprehensive Guide
How to transform complex nested structures into simple, flat arrays

Search for a command to run...
How to transform complex nested structures into simple, flat arrays

No comments yet. Be the first to comment.
Node.js doesn't use multiple threads to handle concurrency — and that's not a weakness. Here's exactly how it pulls off handling thousands of connections without breaking a sweat.

Stop confusing params and query in Express.js

Table of Contents What is cURL — in very simple terms Why programmers need cURL Making your first request Understanding request and response Using cURL to talk to APIs Common mistakes beginners

A practical guide to where files live, how to expose them over HTTP, and the security rules you cannot skip.

Understanding authentication approaches · stateful vs stateless · when to use each

XP-VISHAL-WEB-DEV-COHORT-2026-BLOGS
24 posts
Nested arrays are a common problem in JavaScript, especially when you are dealing with complex data structures like API responses, databases, or recursive algorithms. Flattening them and making them a multi-level array into a single-level array is a frequent task that every developer has done many times.
In this article, we will explore what a nested array is, how to flatten an array, and convert a multi-dimensional array into a single-level array, and various ways to flatten an array in JavaScript. I shall focus on problem-solving and thinking.
Just suppose you went to meet your friends. You entered the lawn and met some friends, and you realized your other friends are in another room. You entered the big room and found that your some of your friends are in a small room that is located in your room.
Same when you're dealing with a nested array, same problem. Now, you make a group message and tell them to come to a hall, and you can meet all your friends in one place.
Exactly when you make a nested array into a flattened array, all your elements will be placed where you want.
A nested array (or multi-dimensional array) is an array that contains other arrays as its elements
For example
const nestedArray = [1, [2, 3], [4, [5, 6]]];
Visually
A nested array can go deep without a mindful manner, and its structure is not always regular.
Flattening is useful in many scenarios:
Data normalization: When you receive a nested array from an API, you need to flatten it for processing. (e.g., render the list in ui)
Search and filtering: Searching for an element in a deeply nested array is always easier on a flattened array
Mathematical Operations and Methods: Find the sum of all elements. Min-max needs to use array methods to apply, like map, reduce, and filter, which require a flattened array.
Simplifying communication: Passing the flat array is often simpler than dealing with a nested array.
Flattening an array means converting it from a nested structure into a one-dimensional array where all elements (no matter how deep) appear in order.
For example:
const flattenArray = [ 1, 2, 3, 4, 5, 6, 7, 8, ]
Visually
JavaScript provides several ways to flatten an array, some of which are built in and some are manual implementations. Let's explore one by one with examples.
Array.prototype.flat() (ES2019)The simplest and most modern way is to use the built-in method flat() . It accepts an optional depth parameter (default = 1) that specifies how deep the flattening should go.
const arr = [1, [2, 3], [4, [5, 6]]];
console.log(arr.flat()); // output: [1, 2, 3, 4, [5, 6]] (depth 1)
console.log(arr.flat(2)); // output: [1, 2, 3, 4, 5, 6] (depth 2)
console.log(arr.flat(Infinity));
// output: [1, 2, 3, 4, 5, 6] (fully flat)
Pros: Clean, fast, handles depth.
Cons: Not available in very old environments (but can be polyfilled).
reduce() and concat()A classic approach combines reduce with concat one level at a time. You can wrap it in a recursive function to handle arbitrary depth.
function flattenOnce(arr) {
return arr.reduce((acc, val) => acc.concat(val), []);
}
const arr = [1, [2, 3], 4]; console.log(flattenOnce(arr)); // [1, 2, 3, 4]
For deep flattening, you can check if an element is an array and recursively flatten it:
function flattenDeep(arr) {
return arr.reduce((acc, val) =>
acc.concat(Array.isArray(val) ? flattenDeep(val) : val), []);
}
const nested = [1, [2, [3, 4], 5]]; console.log(flattenDeep(nested)); // [1, 2, 3, 4, 5]
Pros: Pure functional, no mutation.
Cons: Recursive depth may cause stack overflow for extremely deep arrays.
You can write a recursive function that iterates through the array and pushes non-array items to a result.
function flatten(arr) {
let result = [];
for(let i = 0; i< arr.lemgth ; i ++ ){
result = result.concat(flatten(arr[i]));
} else{
result.push(arr[i]);
}
return result;
}
Step-by-step for [1, [2, [3]]]:
Start with result = []
First element 1 → push → [1]
Second element [2, [3]] is array → call flatten([2, [3]])
Inside: result2 = []
2 → push → [2]
[3] is array → call flatten([3])
3 → push → [3]result2 becomes [2, ... [3]] → [2, 3]
Outer result becomes [1, ... [2, 3]] → [1, 2, 3]
Pros: Clear logic, easy to understand.
Cons: Recursion depth limit, creates intermediate arrays.
To avoid recursion, you can use a stack (LIFO) to process elements iteratively. This is more memory-efficient and avoids stack overflow.
function flattenIterative(arr) {
const stack = [...arr];
const result = [];
while (stack.length) {
const next = stack.pop();
if(Array.isArray(next)) {
stack.push(...next);
}else{
result.push(next);
}
}
return result.reverse();
}
How it works:
Start with a copy of the array as a stack.
While stack is not empty, pop the last element.
If it’s an array, push its elements back onto the stack (they will be processed later).
If it’s a primitive, add to result.
Finally reverse the result because we processed from the end.
Example for [1, [2, [3]]]:
Stack = [1, [2, [3]]], result = []
Pop [2, [3]] → it’s an array, push 2 and [3] → stack = [1, 2, [3]]
Pop [3] → array, push 3 → stack = [1, 2, 3]
Pop 3 → primitive, result = [3]
Pop 2 → result = [3, 2]
Pop 1 → result = [3, 2, 1]
Reverse → [1, 2, 3]
Pros: No recursion, handles deep arrays.
Cons: Slightly more complex, requires reversal.
toString() and split() (Quick but Limited)For arrays containing only numbers (or strings without commas), you can abuse toString():
const arr = [1, [2, [3, 4]]]; const flat = arr.toString().split(',').map(Number);
console.log(flat); // [1, 2, 3, 4]
But this fails if elements are objects or contain commas. Not recommended for general use.
Interviewers often ask you to implement a flatten function to test your understanding of recursion, iteration, and edge cases. Here are typical variations:
White a function that completely flatten an Array.
function flattenArr(arr){
return arr.reduce((acc, value)=>
acc.concat(Array.isArray(value) ? flattenArr(value): value),[]
)
}
2. Flatten with Depth Control
Implement a function that accepts a depth parameter, similar to Array.flat().
function flattenDepth(arr, depth = 1) {
if (depth <= 0) return arr.slice(); // no flattening
return arr.reduce((acc, val) => {
if (Array.isArray(val) && depth > 0) {
acc.push(...flattenDepth(val, depth - 1));
} else {
acc.push(val);
}
return acc;
}, []);
}
JavaScript’s flat() automatically removes empty slots. Your custom implementation should also handle them.
For very large arrays, the iterative stack method is often faster and avoids recursion limits. Mentioning this shows depth.
Non-array elements: keep as is.
Empty arrays: should disappear (flatten to nothing).
Arrays containing null or undefined: should be preserved.
Very deep nesting: stack overflow risk in recursive methods.
When approaching flattening in an interview or real-world task, think like this:
Understand the input and output: Input is a nested array, output is a flat array.
Consider the depth: Do you need shallow or deep flattening?
Choose a strategy: Recursion, iteration, or built-in method?
Handle edge cases: What if there are empty arrays? What if there are objects?
Optimize if needed: For large data, prefer iterative stack.
Let’s walk through a manual flattening of [1, [2, [3, 4], 5]] using a mental model:
Start with an empty result [].
Element 1 → not array → result = [1]
Element [2, [3, 4], 5] → array → recursively flatten it:
Sub-result []
2 → [2]
[3, 4] → array → flatten:
3 → [3]
4 → [3, 4]
Add [3, 4] to sub-result → [2, 3, 4]
5 → [2, 3, 4, 5]
Add sub-result to main result → [1, 2, 3, 4, 5]
This recursive decomposition mirrors the tree structure.
Here’s a simple diagram showing the flattening process:
Original nested structure:
[ 1, [ 2, 3 ], [ 4, [ 5, 6 ] ] ]
Flatten step-by-step (depth-first):
1. Start with empty result []
2. See 1 → add [1]
3. See [2,3] → expand:
- add 2 → [1,2]
- add 3 → [1,2,3]
4. See [4,[5,6]] → expand:
- add 4 → [1,2,3,4]
- see [5,6] → expand:
- add 5 → [1,2,3,4,5]
- add 6 → [1,2,3,4,6]
Result: [1,2,3,4,5,6]
Flattening arrays is a fundamental skill in JavaScript. Whether you use the modern flat() method, a recursive reduce, or an iterative stack, understanding the underlying logic helps you solve similar problems (like deep object traversal). When preparing for interviews, practice implementing your own flatten function with depth control and edge cases. Remember to consider performance and readability based on your use case.