Write a function that flattens a nested array of any depth.
Loop through the array; if an item is an array, flatten it recursively and add its items, otherwise add the item. The built-in shortcut is arr.flat(Infinity).
Explain it simply
Imagine boxes inside boxes inside boxes. You open a box, and if you find another box, you open that too, until only loose items are left.
That is recursion: the function calls itself for every inner array. reduce makes the code short: start with an empty list and, for each item, either append the item or append the flattened version of the inner array.
You can also ask the language: arr.flat(depth) flattens depth levels, and Infinity goes all the way. Interviewers often ask for the manual version anyway.
Line by line
function flatten(arr) {
return arr.reduce((out, item) => {
return Array.isArray(item) ? out.concat(flatten(item)) : out.concat(item);
}, []);
}
console.log(flatten([1, [2, [3, [4]]], 5])); // Output: [1,2,3,4,5]
console.log(flatten([])); // Output: []
console.log([1, [2, [3, [4]]]].flat(Infinity)); // Output: [1,2,3,4]What to say in the interview
"I recurse: for each element, if it is an array I flatten it and concat, otherwise I concat the value. Array.flat(Infinity) does the same natively. For very deep nesting I would use an explicit stack to avoid hitting the call stack limit."
Complexity
Time O(n) for n total items, though repeated concat can add copying cost. Space O(n) for the output plus O(d) recursion depth.
Common mistakes
- Using flat() with no argument and expecting full flattening. The default depth is 1.
- Mutating a shared output array without returning it in the recursive call.