JavaScript: The Recent Parts

flat & flatMap

Kyle Simpson

Kyle Simpson

You Don't Know JS
JavaScript: The Recent Parts

Check out a free preview of the full JavaScript: The Recent Parts course

The "flat & flatMap" Lesson is part of the full, JavaScript: The Recent Parts course featured in this preview video. Here's what you'd learn in this lesson:

Kyle introduces new array methods .flat and .flatmap that augment nested arrays.


Transcript from the "flat & flatMap" Lesson

>> Kyle Simpson: Array find and array includes are good examples of helper methods that we normally would be bringing in from something like Lodash or some other kinda utility library. And we're bringing them into the so-called JavaScript standard library. And another example of bringing in items to the JavaScript standard library that are almost always found in other utility libraries is flat and flatMap.

Both of these were added just recently. This is a hot topic right hot off the presses. flat and flatMap have been added to JavaScript. And by the way, some of you over the last 6 to 12 months, you may have heard about SmooshGate. And if you were following along on the tech Twitters, you might have seen a big roohah about somebody on TC39 made a joke that they couldn't call it what they wanted to call it, which was flatten, because it conflicted with some MootTool's method name from 2005.

And so somebody on TC39 made a joke, well, why don't we just call it array.smoosh? And that was a joke, but a whole bunch of people thought that that was a real TC39 proposal. And then it just escalated and people yelled and argued and all of that stuff.

Thankfully, we did not get array smoosh, but what we did get is array.flat and .flatMap. So let's take a quick look at those. If you have either already created or actually, through some various ways, have created a nested array, this is the use case for where you might want to flatten that array.

So you notice this line 2 here, I've got this nested array, including in the middle of it, this sort of empty nested thing. And if I flatten it with a flatten level of 0, that has the effect of doing nothing to it. But if I flatten it with the default of 1, like we see on line 7, you'll notice that one level of nesting is removed.

So the array 2, 3 has been just flattened down into the main array. The nested array is now just a single array. This is line 8, and then the 4 and the 5 have been nested down one level. So we just have the array 5, so that's what happens by default.

That's one level of unnesting, if you will, or flattening. But flat also takes values that you can tell it how many levels you wanna do, so you can give it a number like 2. And basically, if you wanna have it do all the flattenings, just give it a really big number.

[LAUGH] Because no matter how deep it is, if you give it some really big number, like infinity or something, it's gonna just flatten all of them. So this is, again, one of those common utilities that you see across lots of different libraries, and now we have a built-in version of it.

And when we get something built into JavaScript, it's actually much better for us to embrace and use the built-in standard thing rather than to continue to rely upon the userland libraries. Not that those are bad, those are fantastic libraries and they're the reason why we get these things added into the language.

It just means that we shouldn't continue to use those as crutches when we have something built-in. So flat works pretty well, when you just have an array and you want to do some operation on it. But what if you're also doing some other operations like mapping things? Well then you might come across the need to do both the flatten and the mapping at the same time.

This is extremely common in functional programming, which is beyond the scope of what we'll discuss here. But there is a number of techniques within functional programming where you run across the need to both map something and flatten something. Best way for me to illustrate that would be to say, if you ended up mapping an array of values to an array of subarrays.

In this case, I'm calling I've got this function tuples that is producing, from the array [1, 2, 3], it is an array of subarrays where the first element in the tuple is the doubling of the number and the second array is the doubling that is then stringafied. Why would you do that?

Well, again, this is more complex stuff in terms of setting up values to be used in function compositions and other functional programming techniques. Quick little plug, I have a functional programming course here on Frontend Masters. So go check that out if you're curious about more of those. But even if you had this already having been created and you wanted to map it down to this flattening, the flatMap is gonna do it nicely.

You could do the map and then do the flatten, that's what were doing with line 6, 7 and 8. We do the mapping with our good old friend, the standard .map call. And then we called .flat on it, and that ends up flattening the array down from its tuples, down into all those values being together.

And that's our desired end result, but the way we got there is a little less desirable because we ended up creating an intermediary array that then had to be recreated with its flattened result. So flatMap is basically flatten while you map instead of flattening after you map. Conceptually, they're the same thing but from a performance and implementation perspective, we end up with a better result if that that's what we need to do if we need to do both steps.

You see on line 11 I use a flatMap utility. And I return it tuple and those are immediately flattened in. Notice by the way that this flattening is one level. So where we had the flat, where we could control the level, here the assumption with flatMap is you're always just gonna go one level flattened.

So if you did need to go additional levels, you would have to use an additional call to flat.
>> Kyle Simpson: One other interesting implication of the idea of flatMap is that you can actually turn a mapping operation into something that either adds or removes elements from an array. We typically think of a map as only producing a new array with the same number of items as the original array.

But if we, for example, were to return a tuple, a subarray like we're doing on line 3, that would have the effect of adding a new element into the array at that position. But if we did the reverse, which was to return an empty array, since empty arrays don't have any contents, when they get flattened, they just go away.

That is the effect of removing an element from the array. So here, I am removing the odd numbers and I am adding in elements for the even numbers. I'm adding the even number as well as its doubled value. So we start out with 1, 2, 3, 4, 5, 6 and we end up with a 2, 4, a 4, 8 and a 6, 12.

We removed an item and then replaced it with another item. So that's a cool little trick that flatMap allows you to do, is both add and remove items depending upon some scenario. So now we have array flat and array flatMap. Again, those have landed in ES2019. They'll be officially standardized a bit later here in the year 2019.

And then, you should already see several of your browsers having implemented this. Notably, it's already in V8, so it's in Chrome and in all your sort of Node and Electron sort of environments. So this is definitely something that's rolling out quick. And it's also very easy to have been polyfilled.

So you can use polyfills or transpolations like Babel and start using this today in your code.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now