EasyPayPalGoogleAmazonLyftMetaThoughtSpot

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 null and undefined.
  • Empty sub-arrays should be skipped (they contribute no elements).

Playground

Hint 1

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.

Hint 2

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?

Hint 3

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 flattenArray on it, then spread (...) the returned values into result.

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]]]:

  1. See 1 — not an array → push to result
  2. 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. See 4 → push. Return [3, 4]
    • Spread [3, 4] into result → [2, 3, 4]
  3. 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.

Resources