JavaScript overview — using flat and flatMap

With the aims of productivity, let skip the introduction of a new problem by starting with the e-commerce use case presented in the previous post (JavaScript overview — using filter, map, and reduce)and the business requirements we left undone. As we know, the plain data structure we are working with goes as follows:

Now we are assigned to the requirement presented below, and we can solve it by using as many approaches as we want, but take in mind our main task would be to use the flat and flatMap functions.

For the order whose total value exceeds $5500.00 apply the 5% discount over the entire buy.

Taking a look at the data model, to get the total of the order we should seek the prices of every product by the quantity specified on the line item.

Flattening

Flattening an array means to take an array with items (first level) that may contain at least one sub-array as a child (second level) and subsequently, this last child could have a few children (third level) until the innermost array ends with the offspring chain (i-est level).

Suppose we have a multilevel array with numbers, where we don’t care about its distribution or its contextual meaning:

[-2, [2, [30, 24], 15, 20], [99], 21, 5, [10, [66], 0]]

With little effort, we can take the elements by their corresponding level. At the first level (topmost) we have [-2, 21, 5], on the second level items are [2, 15, 20, 99, 10, 0], and at the third level (the innermost) the items left are [30, 24, 66].

The task now is to flatten the levels of the array to obtain a new array where every item stands at the top. As a result we must have [-2, 2, 30, 24, 15, 20, 99, 21, 5, 10, 66, 0].

The way we afford this kind of task on JavaScript is by calling the function flat which simplifies our work just with an optional argument that tells how many levels to flat (or none, implicitly taken as a first-level flattening).

[-2, [2, [30, 24], 15, 20], [99], 21, 5, [10, [66], 0]].flat(2);
//[-2, 2, 30, 24, 15, 20, 99, 21, 5, 10, 66, 0]

If no argument is provided, the flat function would just work over the zero and first level of the array.

[-2, [2, [30, 24], 15, 20], [99], 21, 5, [10, [66], 0]].flat();
//[-2, 2, [30, 24], 15, 20, 99, 21, 5, 10, [66], 0]

To summarize, the flat function takes an optional argument and returns a new array as a result of the transformations made to the original array.

flat([depth]);
  1. the depth defines how many levels must be flattened.

On the other hand, the flatMap function can perform the flattening after mapping each item over the array, but here the flattening is always at the first level. With this constraint, we are incapable of doing certain tasks flat function does.

[-2, [2, [30, 24], 15, 20], [99], 21, 5, [10, [66], 0]]
.flatMap(item => item * 2);
//[-4, NaN, 198, 42, 10, NaN]

The flatMap would try to apply the mapping to the current item on the array, as the example above, the items that are not numbers can not be multiplied by 2 returning a “Not A Number” value on the place where we used to have a sub-array.

The flatMap function takes at the most two arguments and it applies the mapping and the consequent flattening to the original array returning a new one with the corresponding transformations.

flatMap(callback(current [, index]){});
  1. the current item being processed the moment
  2. the index of the current value

Thanks for reading! I hope you enjoyed the article, I will try to upload new content periodically.

Please, let me know if you like the article by leaving a comment or by clicking on the 👏 button. Also, you can follow me on Medium, Twitter, and LinkedIn.