Array Flatten in JavaScript

I like making things with code. This is where I share my projects and the bugs I ran into.
Every time I pack for a trip, my suitcase is never just a big pile of loose stuff. It is organised into pouches. One pouch for chargers and cables, one for toiletries, a little pocket for documents, clothes folded into their own section. A suitcase full of smaller containers, each holding its own things. Looks very neat while packing, and I feel weirdly proud of myself.
But the moment I reach the hotel and need one specific thing, say my phone charger, all that neatness turns into a problem. I do not want to open pouch after pouch hunting for it. So half the time I just tip the entire suitcase out onto the bed, everything in one flat pile, and boom, I can see every single item at once.
That, right there, is array flattening. A nested array is your neatly packed suitcase, containers inside containers. Flattening is tipping it all out into one single flat layer, where every value finally sits at the same level. Chalo, let me show you properly, because this is also a favourite interview question, so it is worth actually understanding, not just memorising.
First, what is a nested array
A nested array is simply an array that has other arrays inside it. Just like a pouch inside your suitcase.
const suitcase = ["passport", ["charger", "cable"], ["shirt", ["socks", "belt"]]];
Look at that carefully. At the top level we have "passport", then a pouch ["charger", "cable"], then another pouch ["shirt", ["socks", "belt"]], and notice that last one has yet another pouch inside it, ["socks", "belt"]. So this array is nested more than one level deep. That idea of depth, how many pouches sit inside pouches, is going to matter a lot in a minute.
Why would you even flatten it
Fair question. Why not leave the pouches as they are?
Because nested data is genuinely annoying to work with. Say you just want to loop over every single item and print it. With a nested array, one simple loop is not enough, you would need loops inside loops inside loops, and you do not even know how deep it goes. Flatten it first, and suddenly a plain single loop, or a clean map or filter, works on everything.
And this is not some rare textbook case. Real data comes nested all the time. An API might send you results in pages, an array of arrays. A form might give you groups of answers. You flatten it into one clean list, and then all the normal array methods just work. Bahut kaam ki cheez hai, trust me.
The easy way: the built-in flat method
JavaScript already gives you a method for this, flat(). The catch, and this is the part people miss, is that by default it only goes one level deep.
const nested = [1, [2, 3], [4, 5]];
console.log(nested.flat()); // [1, 2, 3, 4, 5]
One level, perfect. But watch what happens with something deeper.
const deep = [1, [2, [3, [4]]]];
console.log(deep.flat()); // [1, 2, [3, [4]]]
Dekho, it only opened the first pouch. The pouches inside are still sealed. That is because flat() defaults to a depth of just 1. You can tell it how many levels to go.
console.log(deep.flat(2)); // [1, 2, 3, [4]]
console.log(deep.flat(3)); // [1, 2, 3, 4]
But counting the exact depth by hand is a pain, and often you just want everything opened, no matter how deep. For that, there is a lovely trick.
console.log(deep.flat(Infinity)); // [1, 2, 3, 4]
flat(Infinity) says "keep opening pouches until there are no pouches left." This is the one you will reach for most in real code when you just want a fully flat array and do not care about the levels.
The interview way: write your own flatten
Here is the thing. In an interview, they will almost never let you just call .flat(). They want to see if you actually understand what is happening underneath. "Flatten this array without using the built-in flat method" is one of the most common JavaScript interview questions out there. So let us build it.
The trick is to think like you are unpacking the suitcase by hand. Go through each item. If the item is a normal thing, put it straight into your final flat pile. If the item is itself a pouch, an array, open it up and repeat the exact same process on it. That "repeat the same process on the smaller thing" is recursion, and it is the heart of this.
function flatten(arr) {
let result = [];
for (const item of arr) {
if (Array.isArray(item)) {
result = result.concat(flatten(item)); // it is a pouch, open it and merge
} else {
result.push(item); // it is a plain item, drop it in the pile
}
}
return result;
}
console.log(flatten([1, [2, [3, [4]]]])); // [1, 2, 3, 4]
Walk through it slowly. Array.isArray(item) checks "is this item a pouch or a plain thing." If it is a plain thing, we just push it. If it is a pouch, we call flatten on that pouch, which does the whole thing again on the smaller array, and we merge the result in with concat. It keeps calling itself, going deeper and deeper, until there are no more pouches left. Every level gets opened.
If you like the shorter, cleaner style, the same logic fits neatly into a reduce.
function flatten(arr) {
return arr.reduce((flat, item) => {
return flat.concat(Array.isArray(item) ? flatten(item) : item);
}, []);
}
Same idea, less code. For each item, if it is an array, flatten it first, otherwise use it as is, and concat it onto the growing flat array. If you can write and explain either of these, you have basically answered the interview question.
A common twist: flatten to a specific depth
Once you can do a full flatten, interviewers love to raise the bar, "okay, now flatten only up to a given depth." This is just your recursive version with a counter that ticks down.
function flattenDepth(arr, depth = 1) {
if (depth < 1) return arr.slice(); // no depth left, return as is
return arr.reduce((flat, item) => {
return flat.concat(
Array.isArray(item) ? flattenDepth(item, depth - 1) : item
);
}, []);
}
console.log(flattenDepth([1, [2, [3, [4]]]], 1)); // [1, 2, [3, [4]]]
console.log(flattenDepth([1, [2, [3, [4]]]], 2)); // [1, 2, 3, [4]]
Every time we go one pouch deeper, we reduce depth by one. When depth hits zero, we stop opening and just return whatever is left. That is literally how the built-in flat(depth) behaves under the hood, and now you know why.
Why interviewers love this question
It is not really about flattening arrays. It is a neat little test of whether you understand recursion, whether you know Array.isArray, and whether you can handle a problem where you do not know how deep the data goes. If you can reason through "open a pouch, and if there is a pouch inside, open that the same way," you have shown the exact kind of thinking they are checking for. Soch samajh ke likho, do not just cram it.
Try it yourself
Do not just read it, khud likho. Paste this in and play.
const packed = [1, [2, 3], [4, [5, [6, 7]]]];
// the built-in way
console.log(packed.flat(Infinity)); // [1, 2, 3, 4, 5, 6, 7]
// your own way
function flatten(arr) {
return arr.reduce(
(flat, item) => flat.concat(Array.isArray(item) ? flatten(item) : item),
[]
);
}
console.log(flatten(packed)); // [1, 2, 3, 4, 5, 6, 7]
Change the nesting, go five pouches deep, and confirm both give the same flat pile. Then try writing the depth-limited version from memory, that is the real practice.
Wrapping up
So that is array flattening. A nested array is a suitcase full of pouches inside pouches, and flattening tips it all out into one flat layer where every value sits at the same level. Use flat() for a level or two, flat(Infinity) to open everything, and know how to hand-roll it with recursion, because that is what interviews actually want.
Next time you tip your suitcase onto a hotel bed to find your charger, smile a little, you are running a flatten algorithm in real life.
And if writing your own flatten from scratch felt satisfying, you are going to enjoy the next one, where we rebuild JavaScript's own string methods by hand, the same "implement it yourself" energy that interviews love.
I hope you enjoyed reading this.




