ES2019 introduces the Array.prototype.flatMap method. In this lesson, we'll investigate a common use case for mapping and flattening a multidimensional array. We'll then see how to do this using Array.prototype.reduce, and then refactor the code to do the same thing using the ES2019 .flatMap method.
Instructor: [00:01] Once again, we're looking at an xJS application, and this time we want to see how we're generating the average students that visited a session per individual site. A site can be thought of as a location where students go to take tests.
[00:14] In this case, the overall average students that attend each session is five. This value is derived by taking all the numbers of attendees in the AM and the PM sessions and averaging them together.
[00:24] In an xJS application, we achieve this by piping the data from sites JSON through our JSON parser all the way through to our sites component, binding sites to the component itself. By the time that gets here, that will show up as this.records inside of the component. This.records matches back to the records property of the JSON object, and we can work from there.
[00:51] Prior to ES.19, we didn't have a built-in way to take multiple properties of an object and push them both onto an array. In this case, we want to use our average utility function, which takes a flat array of numeric values and averages them. Because our records contain two numbers that we want to add to our array, we push both of the records onto an array.
[01:14] What comes out of this, if I take all the records and paste them here for clarity, we see they're iterating through each record of the array and plucking off the AM value and the PM value and pushing them onto a resulting array. At the end, we'll end up with something that looks like 1,10 for the first record, 2,4 for the second record, 3,12 for the third, 1,7 for the fourth.
[01:42] We then pass this to our average function in order to average those numbers together. ES.19 simplifies that for us a little bit by introducing the flat map function. The flat map function will iterate over an array, and for each element of the array, it expects you to return an array of zero or more values. Each of the elements of this array will be pushed onto the resulting array.
[02:08] This code is essentially equivalent to before, and if we affixify it, removing the code base as another term, we're left with this. Set the result to count, save, and we get the same output.
[02:23] Again, flat map takes in an array and allows you to transform or map the elements of the array to a different array of any size, all of which will be pushed onto the resulting array.
Good catch Tony! It'll be fixed shortly. Thanks!
Looks like the typo @Tony Whomever pointed out is still present in the transcript.
I also noticed that in the video's description it references Array.prototype.reduce
, but the actual code uses Array.prototype.forEach
.
I like this new method. I've often encountered the problem of wanting to map one array to an array of a different size and being forced either to chain the map
to a filter
or just write a reduce
. Those are both fine solutions, but flatMap
looks like it might be more compact and economical, at least under certain conditions.
That being said, I wonder if it will become easy to abuse this method's flexibility and lose the clarity that the filter
and reduce
syntaxes provide. TBD.
Great lesson! Quick note - code below is showing:
averageCount() { const counts = this.records.forEach(record => { counts.push(record.am, record.pm); }); return average(counts) },
Shouldn'tcounts
be declared as follows?:const counts = [];