As you may have seen if you’ve been following the interwebs lately, these new methods to flatten arrays have triggered quite a bit of a stir. Now known at the #Smooshgate, the gist of it is that Array.prototype.flatten() is being monkey-patched by MooTools, which is still used by some websites, so at some point a suggestion popped-up to name the method smoosh instead of flatten as a joke, to avoid breaking some websites still relying on MooTools. A lot of people took the smoosh suggestion seriously, and quite a bit of keystrokes were lost over this.
Let’s go over them now.
As its name suggests, the flat() method available on the Array prototype returns a new array that’s a flattened version of the array it was called on. Without arguments passed-in, a depth of 1 is assumed. Otherwise, if a number is passed-in as the first argument, it’s used as the maximum depth to flatten the array.
Here’s a simple example:
const animals = [['🐕', '🐶'], ['😺', '🐈']]; const flatAnimals = animals.flat(); // same as: const flatAnimals = animals.flat(1); console.log(flatAnimals); // ['🐕', '🐶', '😺', '🐈']
And notice what happens when the total depth of the array is larger than the maximum depth for the flat method:
const animals = [['🐕', '🐶'], ['😺', '🐈', ['😿',['🦁'], '😻']]]; const flatAnimals = animals.flat(2); console.log(flatAnimals); // ['🐕', '🐶', '😺', '🐈', '😿',['🦁'], '😻']
You can use Infinity if you want to flatten an array of arbitrary depth:
const animals = [['🐕', '🐶'], ['😺', '🐈', ['😿',['🦁'], '😻']]]; const flatAnimals = animals.flat(Infinity); console.log(flatAnimals); // ['🐕', '🐶', '😺', '🐈', '😿', '🦁', '😻']
The flatMap() method available on the Array prototype has the same effect as using the map() method followed by the flat() method with the default depth of 1. In other words, flatMap() maps each value to a new value and then the resulting array is flatten up to a maximum depth of 1.
Here’s an example:
const animals = ['🐕', '🐈', '🐑', '🐮']; const noises = ['woof', 'meow', 'baa', 'mooo']; const mappedOnly = animals.map((animal, index) => [animal, noises[index]]); const mappedAndFlatten = animals.flatMap((animal, index) => [animal, noises[index]]); console.log(mappedOnly); // [['🐕', 'woof'], ['🐈', 'meow'], ['🐑', 'baa'], ['🐮', 'mooo'] console.log(mappedAndFlatten); // ['🐕', 'woof', '🐈', 'meow', '🐑', 'baa', '🐮', 'mooo']
The callback function passed-into flatMap() expects the same arguments as the ones that can be passed-in to the traditional map() method, the first being the current value, the second being the index of the current value in the array and the third being the full array being mapped over.
Support is already pretty good, with the latest version of most recent browsers supporting both methods. For example, the methods are supported in Chrome 69+, Firefox 62+ and Safari 12+. There currently is no support for any version of Internet Explorer or Edge, at the time of this writing.