Array Flatten in JavaScript

Arrays are one of the most fundamental data structures in JavaScript. They allow us to store multiple values in a single variable and perform operations efficiently. While simple arrays are straightforward to work with, real-world applications often involve nested arrays, where arrays exist inside other arrays. Working with such structures introduces the concept of array flattening.
Flattening an array means converting a nested array into a single-level array by removing all levels of nesting. It is a common problem in JavaScript development and frequently appears in coding interviews. Understanding how flattening works not only improves your knowledge of arrays but also strengthens problem-solving skills.
What Nested Arrays Are:
A nested array is simply an array that contains other arrays as elements.
A basic array looks like this:
const numbers = [1, 2, 3, 4];
A nested array looks like this:
const nested = [1, [2, 3], [4, 5]];
This contains arrays inside the main array.
Arrays can be nested multiple levels deep.
const deepArray = [1, [2, [3, [4, 5]]]];
Visualizing it:
[
1,
[
2,
[
3,
[
4,
5
]
]
]
]
Each inner array creates another level of depth.
Think of nested arrays like folders inside folders.
Root
├── 1
└── [2, [3, [4,5]]]
Flattening removes those layers.
Flattened result:
[1,2,3,4,5]
Why Flattening Arrays Is Useful
Flattening is useful because many operations become easier when data exists in one level.
Suppose you receive product categories from an API:
const products = [
["Laptop", "Mouse"],
["Keyboard", "Monitor"],
["Speaker"]
];
Flattening makes processing easier:
["Laptop","Mouse","Keyboard","Monitor","Speaker"]
Now searching, filtering, looping, or transforming data becomes simpler.
Common reasons flattening is useful:
Data normalization
Cleaning API responses
Preparing data for iteration
Searching and filtering
Reducing nested complexity
Mathematical operations
Merging multiple lists
Real-world example:
const scores = [
[80,90],
[70,85],
[95]
];
Flatten:
[80,90,70,85,95]
Then calculating total becomes simple.
const total = scores.flat().reduce((sum,n)=>sum+n,0);
Without flattening this is harder.
Concept of Flattening Arrays
Flattening means taking nested structures and converting them into one-dimensional arrays.
Example:
[1,[2,3],[4,5]]
Step 1:
[1,2,3,4,5]
Deep nesting:
[1,[2,[3,[4]]]]
Flatten:
[1,2,3,4]
Conceptually we:
Visit each item
Check whether item is array
If normal value → add it
If array → open it and process inside values
This thinking is the foundation of flattening.
Pseudo logic:
For every item:
if item is array
flatten it
else
add to result
That is the core idea behind all solutions.
Different Approaches to Flatten Arrays
There are multiple ways to solve this problem.
Using flat()
Modern JavaScript provides built-in flat().
const arr = [1,[2,3],[4,5]];
console.log(arr.flat());
Output:
[1,2,3,4,5]
Default depth is 1.
Nested deeper:
const arr = [1,[2,[3,4]]];
Flatten two levels:
console.log(arr.flat(2));
Output:
[1,2,3,4]
Flatten all levels:
console.log(arr.flat(Infinity));
Output:
[1,2,3,4]
This is the easiest modern approach.
Using Recursion
Recursive solutions are popular in interviews.
function flatten(arr){
let result=[];
for(let item of arr){
if(Array.isArray(item)){
result=result.concat(
flatten(item)
);
}else{
result.push(item);
}
}
return result;
}
Usage:
flatten(
[1,[2,[3,[4]]]]
);
Output:
[1,2,3,4]
How it works step by step:
Input:
[1,[2,[3]]]
Take 1
Add to result --> See [2,[3]] --> Flatten again --> Take 2 --> Add --> See [3] --> Flatten again --> Take 3 --> Add --> Return back upward
Final:
[1,2,3]
This demonstrates recursive thinking.
Using reduce()
Another elegant approach uses reduce.
function flatten(arr){
return arr.reduce(
(acc,val)=>
acc.concat(
Array.isArray(val)
? flatten(val)
: val
),
[]
);
}
Output:
[1,2,3,4]
This combines recursion with functional programming.
Using Loops
Without recursion:
function flatten(arr){
let stack=[...arr];
let result=[];
while(stack.length){
let next=stack.pop();
if(Array.isArray(next)){
stack.push(...next);
}else{
result.unshift(next);
}
}
return result;
}
This uses stack-based thinking.
Often asked in interviews.
Common Interview Scenarios
Array flattening appears often in coding interviews.
Common version:
Flatten this:
[1,[2,[3,[4]]]]
Expected:
[1,2,3,4]
Another popular question:
Write your own flat() polyfill.
Example:
function myFlat(arr){
let result=[];
arr.forEach(item=>{
if(Array.isArray(item)){
result.push(
...myFlat(item)
);
}else{
result.push(item);
}
});
return result;
}
This mimics built-in flat.
Another interview twist:
Flatten only certain depth.
Input:
[1,[2,[3]]]
Depth 1:
[1,2,[3]]
Depth 2:
[1,2,3]
This tests depth handling.
Another common scenario:
Flatten nested objects + arrays.
Example:
[
{id:1},
[{id:2},{id:3}]
]
Expected:
[
{id:1},
{id:2},
{id:3}
]
Interviewers often want reasoning more than syntax.
Problem Solving Thinking Behind Flattening
Rather than memorizing solutions, think about the process.
Ask:
Is current item simple value?
Or another array?
If another array, how do I process inside it?
This naturally leads to recursion.
Tree thinking helps.
Nested arrays behave like trees.
Example:
[1,[2,[3,4]]]
Can be viewed as:
root
/ \
1 array
/ \
2 array
/ \
3 4
Flattening means traversing the tree and collecting values.
This is why flattening teaches deeper algorithmic thinking.
Performance Considerations
For small arrays any method works.
For large deeply nested arrays:
Recursive solutions may hit call stack limits.
Loop stack solutions may be safer.
Built-in flat() is usually optimized.
Interview tip:
Mention time complexity.
For n elements:
Time complexity:
O(n)
Every value visited once.
Space complexity depends on approach.
Usually:
O(n)
Mentioning this shows deeper understanding.
Practical Examples
Combine tags:
const tags = [
["js","react"],
["node"],
["css","html"]
];
const allTags=tags.flat();
console.log(allTags);
Result:
["js","react","node","css","html"]
Shopping cart items:
const cart = [
["Phone","Case"],
["Charger"]
];
Flatten:
["Phone","Case","Charger"]
Useful in real applications.