# How to flatten array using Javascript

## Problem

So you have some nested array but need to flattened it so you use it inside your codebase. There are actually a couple of ways to do it.

Here is what we are gonna take a look at;
- Array.prototype.flat()
- Reduce and Concat Solution
- Recursive Solution
- Stack Solution


## 1. Array.prototype.flat() Solution

The flat() method creates a new array with all sub-array elements concatenated into it recursively up to the specified depth.

- **Returns:** A new array with the sub-array elements concatenated into it.

```jsx
const arr1 = [0, 1, 2, [3, 4]];

console.log(arr1.flat());
// expected output: [0, 1, 2, 3, 4]

const arr2 = [0, 1, 2, [[[3, 4]]]];

// We can also give optional depth argument to flat function
console.log(arr2.flat(2));
// expected output: [0, 1, 2, [3, 4]]
```

Flat can  also work on nested arrays

```jsx
console.log(arr2.flat(Infinity))
// expected output: [0, 1, 2, 3, 4]
```

Or it can remove empty spots in the array

```jsx
const arr5 = [1, 2, , 4, 5];
arr5.flat();
// [1, 2, 4, 5]
```

## 2. Reduce and Concat Solution

```jsx
const flatten = (arr) => {
  return arr.reduce(function (flat, toFlatten) {
    return flat.concat(Array.isArray(toFlatten) 
			? 
			flatten(toFlatten) 
			: toFlatten);
  }, []);
}

flatten([[1, 2, 3], [4, 5]]); // [1, 2, 3, 4, 5]
flatten([[[1, [1.1]], 2, 3], [4, 5]]); // [1, 1.1, 2, 3, 4, 5]
```

## 3. Recursive Solution

We can also apply recursive solution with the help of concat function

```jsx
const flattenArray = (input) => {
  let result = []

  if (!Array.isArray(input)){
    return input
  }

  for (let data of input) {
    result = result.concat(flattenArray(data))
  }

  return result;
}

let arr = ["a", 0, [1, 2], 3, [[5, 6], [[8, 9]]]]

console.log(flattenArray(arr))
// ["a", 0, 1, 2, 3, 5, 6, 8, 9]
```

## 4. Stack Solution

We can also solve this by the help of stack data structure

```jsx
// non recursive flatten deep using a stack
// note that depth control is hard/inefficient as we will need to tag EACH value with its own depth
// also possible w/o reversing on shift/unshift, but array OPs on the end tends to be faster
function flatten(input) {
  const stack = [...input];
  const res = [];
  while(stack.length) {
    // pop value from stack
    const next = stack.pop();
    if(Array.isArray(next)) {
      // push back array items, won't modify the original input
      stack.push(...next);
    } else {
      res.push(next);
    }
  }
  // reverse to restore input order
  return res.reverse();
}

const arr = [1, 2, [3, 4, [5, 6]]];
flatten(arr);
// [1, 2, 3, 4, 5, 6]
```

## Links

- [Array.prototype.flat() - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat)

- [Flatten an array using javascript](https://dev.to/nandkk05/flatten-an-array-using-javascript-568l)

- [Merge/flatten an array of arrays](https://stackoverflow.com/questions/10865025/merge-flatten-an-array-of-arrays)
