Celebrating JavaScript .flat()
Tags: beginners, codenewbie
Published: 2020-05-09 04:01:02

I’m a little late to the party and this was *so* last year, but JavaScript finally has a built-in array flattening method so I’m dedicating this post to `flat()`, a kind of belated one-year birthday celebration if you will. 

![pokemon birthday GIF](https://media.giphy.com/media/mcJohbfGPATW8/giphy.gif)

`flat()` and another array flattening method `flatMap()` were introduced with ECMAScript 2019 / ES10. Before this, you would have to flatten your array the old fashioned way of doing it yourself using a combination of `reduce()` and `concat()`. 

*Note-I'll just be covering `.flat()` in this post, so keep an eye out for my upcoming post that will go into `flatMap()`.*

###Browser and Node.js Version Compatibility 
Even with these latest features, it doesn’t mean you’ll be able to use these methods everywhere yet. `flat()` is supported in the majority of web browsers, but not all and I’m sure you know which one I’m talking about (it rhymes with pinternet texplorer). 

To check browser compatibility for any features, I head to [Can I use](https://cariuse.com).  

Another thing to look out for is if your computer’s version of Node.js is out of date (guilty), `flat()` or any newer features will not work in your terminal’s Node.js REPL. This is also a plug to use the terminal REPL, aka Read-Evaluate-Print-Loop, as it's an easy way to test out Node features when you’re unsure about something. All you have to do is type in `node` and you’re on way to NodeLand. Google Chrome's DevTools Console is an excellent REPL as well.

###flat()
The **`flat()` method creates and returns a new array with all the sub-array elements concatenated onto it recursively up to the depth specified.**

####Syntax
```javascript
array.flat([depth]);
// depth is an optional parameter that specifies how deep the 
// nested array structure should be flattened. It is 1 by default.
```

If you don't specify a depth, it is 1 by default. A good **trick I utilize to quickly determine the depth is count the number of opening brackets - 1.** Or in a pinch with an undetermined level amount, you can use `Infinity` to capture the deepest level possible. 

```javascript
const arr1 = ['birthday', 'celebration', ['ice cream', 'cake']];
arr1.flat(); // ['birthday', 'celebration', 'ice cream', 'cake']

const arr2 = ['birthday', 'celebration', ['ice cream', ['cake']]];
arr2.flat(); // ['birthday', 'celebration', 'ice cream', ['cake']];
arr2.flat(2); // ['birthday', 'celebration', 'ice cream', 'cake'];

const arr3 = [2, [3, 4, 6, [7, 8, [9, 10, [11]]]]];
arr3.flat(4); // [2, 3, 4, 6, 7, 8, 9, 10, 11]

// passing in Infinity as parameter will capture the deepest level
arr3.flat(Infinity); // [2, 3, 4, 6, 7, 8, 9, 10, 11]
```
####Use to Remove Empty Items in Array
You can also use `flat()` to easily remove empty items in arrays. This includes empty arrays
```javascript
const arr4 = ['party', 'soirée', , 'bonanza'];
arr4.flat(); // ['party', 'soirée', 'bonanza']

const arr5 = ['fete', 'gala', [], , 'shindig'];
arr5.flat(); // ["fete", "gala", "shindig"]
```
###Alternatives
Somewhere that comes to mind where I can’t use `flat()` as of writing is Leetcode. But never fear, you can flatten your array as you did before mid-2019: writing your own function using a mix of `reduce()`, `concat()`, and recursion.

####Single-level Flatten
```javascript
const arr6 = ['carrot cake', 'birthday cake', ['cheesecake', 'chocolate cake']];

arr6.reduce((acc, val) => acc.concat(val), []); 
// [ 'carrot cake', 'birthday cake', 'cheesecake', 'chocolate cake' ]
```

####Deeper Flatten using Recursion
To get deep level flattening, you can use recursion with `reduce()`, `concat()`, and `isArray()`. Your function can take an optional parameter of depth level, and you can set it to 1 as the default. Below is the solution from [MDN web docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat).

```javascript
const arr7 = ['carrot cake', ['birthday cake', ['cheesecake', ['chocolate cake']]]];

function flatDeep(arr, d = 1) {
  return d > 0 ? arr7.reduce((acc, val) => acc.concat(Array.isArray(val) ?
     flatDeep(val, d - 1) : val), []) : arr.slice();
};

// deepFlatten(arr7, 3); // ["carrot cake", "birthday cake", "cheesecake", "chocolate cake"]
```

`flat()` is a great addition to the JavaScript Array toolbox and I’ll be using this method going forward when supported. Thanks for following along and helping to celebrate `flat()`'s year of existence. Come back next week when when I perform a proper ceremony for `flatMap()`. Happy coding!

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