# JavaScript Interview — how to flatten an array

Problem: You have a nested array and you need all elements to be flat, no sub arrays.

Ex: [1, 2, [3, [4, 5]]]

There are some hurdles to jump over to make this truly efficient.

- [].concat based solutions: not efficient as they create new arrays and that consumes precious memory
- Recursive solutions: generally pretty good; call stack is the limit, might complicate the logic of how to join the data together

A better solution modifies the array in place and doesn’t depend on a large stack. A blueprint looks like this:

`function flatten(arr) {`

...

while(!isFlat)

// flatten some more

}

We will need the following tracked:

- A variable to denote if we are at the end of the array (to exit a loop)
- The index of the array (since this isn’t a for loop implementation)

Then, we need nested while loops because we will iterate the array manually. We need to do this because the array length will be changing as we flatten it each time.

function flatten(arr) {

let reachedEnd = false;

let idx = 0;

while (!reachedEnd) {

// arrays can be multi-nested [[]], hence the inner while

while(Array.isArray(arr[idx])) { ... flatten ...} idx++; // reached end after enough iterations

} return arr;

}

With the skeleton above we can fill in the blanks:

function flatten(arr) {

let reachedEnd = false;

let idx = 0;

while (!reachedEnd) {

while(Array.isArray(arr[idx])) {

arr.splice(idx, 1, ...arr[idx]);

} if (idx === arr.length) {

reachedEnd= true;

} idx++;

} return arr;

}

Next steps: what if we wanted to add a depth to the flattening as well?

Well, we just need to add one variable to track the current depth and add a check in the inner while loop and we’re done:

function flattenToDepth(arr,depth = 1) {

let reachedEnd = false;

let idx = 0;

while (!reachedEnd) {let atDepth = 1;while(Array.isArray(arr[idx])&& atDepth < depth) {

arr.splice(idx, 1, ...arr[idx]);

atDepth++;

} if (idx === arr.length) {

reachedEnd= true;

} idx++;

} return arr;

}