Skip to main content
Madhukar
All Articles

Array Flatten in JavaScript: Concepts, Approaches, and Interview Scenarios

July 30, 20265 min read
Interview PrepJavaScriptData StructuresAlgorithms
Array Flatten in JavaScript: Concepts, Approaches, and Interview Scenarios

What nested arrays are

A nested array is simply an array containing other arrays as items, instead of only plain values:

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

Here, nested has three top-level items — 1, [2, 3], [4, [5, 6]] — but two of those items are themselves arrays, and one of those nested arrays contains yet another array inside it. This kind of structure shows up constantly in real data: a list of categories each containing their own list of items, comment threads with nested replies, or grouped API responses.

Why Flattening Arrays Is Useful

Flattening means taking a nested array and producing a single, flat array containing all the same values, with no nesting left at all:

[1, [2, 3], [4, [5, 6]]]  →  [1, 2, 3, 4, 5, 6]

Real reasons this matters

  • Simpler iteration — a flat array can be looped over, mapped, or filtered directly, without writing special-case logic to handle values that might themselves be arrays
  • Combining grouped data — if an API returns results grouped by category (an array of arrays), flattening merges them into one unified list for display or further processing
  • Cleaner aggregate calculations — summing, counting, or searching across nested data is far simpler once everything sits at the same, single level

Concept of Flattening Arrays

The core idea: for every item in the array, check whether it’s itself an array. If it is, “unwrap” it and process its contents the same way; if it isn’t, keep it as-is in the final result.

This naturally suggests a recursive way of thinking: flattening a nested array is really just “flatten each item, and if that item is itself an array, flatten that the same way” — the same small rule, applied repeatedly, at every level of nesting.

Different Approaches to Flatten Arrays

Approach 1: The built-in flat() method

JavaScript provides Array.prototype.flat() directly:

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

nested.flat(); // [1, 2, 3, 4, [5, 6]] — only one level deep by default
nested.flat(2); // [1, 2, 3, 4, 5, 6] — two levels deep
nested.flat(Infinity); // [1, 2, 3, 4, 5, 6] — flattens fully, regardless of depth

By default, flat() only flattens one level — pass a number for how many levels deep to flatten, or Infinity to flatten completely, no matter how deeply nested the array is.

Approach 2: Writing it manually with recursion

Understanding how to build this yourself is exactly what most interview questions are really testing:

function flattenArray(arr) {
let result = [];

for (let item of arr) {
if (Array.isArray(item)) {
result = result.concat(flattenArray(item)); // recursively flatten this nested item
} else {
result.push(item);
}
}

return result;
}

flattenArray([1, [2, 3], [4, [5, 6]]]); // [1, 2, 3, 4, 5, 6]

Walking through the logic: for each item, check if it’s an array. If it is, recursively flatten that item first, then merge its results in. If it’s just a plain value, push it directly into the result. The recursion is what lets this handle any depth of nesting, not just one or two levels.

Approach 3: Using reduce()

The same idea, expressed with reduce() instead of an explicit loop:

function flattenArray(arr) {
return arr.reduce((flat, item) => {
return flat.concat(Array.isArray(item) ? flattenArray(item) : item);
}, []);
}

This is more compact, but follows the exact same logic underneath: build up a result, recursively flattening any item that’s itself an array.

Approach 4: Using a stack (iterative, no recursion)

For very deeply nested arrays, recursion can theoretically hit a call-stack limit. An iterative version using a stack avoids that entirely:

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

while (stack.length) {
const next = stack.pop();
if (Array.isArray(next)) {
stack.push(...next); // push its contents back onto the stack to process
} else {
result.unshift(next); // maintain original order
}
}

return result;
}

This achieves the same result without ever calling the function itself again — useful to know exists, even if it’s less commonly needed in everyday code.

Common Interview Scenarios

“Flatten this array without using flat()”

This is the most common version — testing whether you understand the underlying recursive logic, not just whether you know a built-in method exists. The recursive approach (Approach 2) is the expected answer here.

“Flatten an array exactly one level deep”

function flattenOneLevel(arr) {
let result = [];
for (let item of arr) {
if (Array.isArray(item)) {
result = result.concat(item); // only unwrap this level, don't recurse further
} else {
result.push(item);
}
}
return result;
}

flattenOneLevel([1, [2, 3], [4, [5, 6]]]); // [1, 2, 3, 4, [5, 6]]

The key difference from full flattening: don’t recursively call the function on nested items — just merge one layer, leaving anything nested deeper than that untouched.

“Flatten an array and remove duplicates”

function flattenUnique(arr) {
const flat = flattenArray(arr);
return [...new Set(flat)];
}

flattenUnique([1, [2, 2], [3, [1, 4]]]); // [1, 2, 3, 4]

Combines the flattening logic with Set (which automatically discards duplicate values) — a common follow-up variation testing whether you can compose solutions rather than just memorize one fixed pattern.

“What’s the time complexity of your solution?”

A reasonable follow-up interviewers often ask. The recursive approach visits every value in the nested structure exactly once, so it runs in O(n) time, where n is the total number of individual (non-array) values across every level of nesting — being able to explain why that's true (every value is processed once, and only once) matters as much as the number itself.

Final Takeaway

Flattening an array is a small problem with an outsized amount to teach — recursion, iteration, and how to reason clearly about nested structures all show up in a problem simple enough to fully understand end to end. The built-in flat() method is the right tool for real production code. But understanding how to build that same behavior yourself — recursively unwrapping nested arrays one item at a time — is exactly the kind of fundamental problem-solving skill interviews are actually trying to assess, and it's a skill that transfers directly to plenty of other nested-structure problems well beyond arrays alone.

Frequently Asked Questions

Should I always use flat(Infinity) in real projects instead of writing my own function?

> Yes, generally — flat() is well-tested, optimized, and clearly communicates intent. Writing your own flattening logic is primarily valuable for learning and interview preparation, not something to prefer over the built-in method in everyday production code.

Does flat() work on deeply nested arrays without a performance problem?

> flat() is implemented natively and handles reasonably deep nesting well. Extremely deep or unusual structures are rare in typical application data, so this is rarely a practical concern outside of specifically adversarial interview edge cases.

Why would recursion hit a stack limit, and how does the stack-based approach avoid it?

> Each recursive call adds a new frame to the call stack, and extremely deep nesting could theoretically exceed the engine’s stack size limit. The iterative, stack-based approach (Approach 4) processes nested items using an explicit array as a stack instead of actual function recursion, avoiding that limit entirely.

Is Array.isArray() the right way to check if something is an array?

> Yes — it’s the standard, reliable way to check specifically for arrays in JavaScript, and it correctly distinguishes arrays from other object types that might otherwise seem similar.

Originally published by Mr Madhukar

Read the complete article on Medium with full formatting & reader responses.