Flatten Array
Prompt
Implement a flattenArray function that takes a nested array and returns a new single-level array with all elements in order.
Imagine the native Array.prototype.flat() method doesn't exist — you need to build it from scratch.
Requirements:
- The function should handle any depth of nesting, not just one level.
- All values should be preserved, including
nullandundefined. - Empty sub-arrays should be skipped (they contribute no elements).
Playground
In your flattening process, you'll need to determine whether an element in the inputArray is itself an array. The Array.isArray function can be very useful here to check if an element needs further flattening.
When you encounter a nested array within your inputArray, think about how recursion can be used. How can you call flattenArray itself to handle these nested arrays?
When you recursively flatten a sub-array, you get back a flat array. Use the spread operator (...) to unpack those elements into your result instead of pushing the array itself.
Solution
Explanation
The idea is simple: walk through every element of the array. If it's a regular value, keep it. If it's another array, flatten that too. Recursion handles the "any depth" requirement naturally.
The solution
function flattenArray(arr) {
const result = [];
arr.forEach((element) => {
if (Array.isArray(element)) {
result.push(...flattenArray(element));
} else {
result.push(element);
}
});
return result;
}Step by step
For each element in the array, we ask one question: is this an array?
- No — push it straight into
result. - Yes — recursively call
flattenArrayon it, then spread (...) the returned values intoresult.
The spread operator is critical here. Without it, result.push(flattenArray(element)) would push a nested array into the result — exactly what we're trying to avoid. The ... unpacks the returned array into individual arguments to push.
Walking through an example
Given [1, [2, [3, 4]]]:
- See
1— not an array → push to result - See
[2, [3, 4]]— it's an array → recurse- See
2— not an array → push to result - See
[3, 4]— it's an array → recurse- See
3→ push. See4→ push. Return[3, 4]
- See
- Spread
[3, 4]into result →[2, 3, 4]
- See
- Spread
[2, 3, 4]into result →[1, 2, 3, 4]
Why Array.isArray?
You might think typeof element === 'object' could work, but that's true for null, plain objects, and other things that aren't arrays. Array.isArray() is the reliable way to check.
Bonus: using reduce
The same logic can be written more concisely with reduce:
function flattenArray(arr) {
return arr.reduce((result, element) => {
return result.concat(
Array.isArray(element)
? flattenArray(element)
: element
);
}, []);
}reduce accumulates values into a single result. For each element, we concat either the recursively flattened sub-array or the element itself. This is functionally identical to the forEach version — pick whichever reads more clearly to you.