DEV Community

jkap100
jkap100

Posted on • Edited on

Using the JavaScript array method flatMap()

INTRODUCTION - flatMap()

This tutorial will demonstrate how to use the map(), flat() and flatMap() array methods in JavaScript. flatMap() is a newer array method which was introduced in es2019. As described by MDN web docs flatMap can be used as a way to add and remove items (modify the number of items) during a map. In other words, it allows you to map many items to many items (by handling each input item separately), rather than always one-to-one. In this sense, it works like the opposite of filter. In simple
terms, this method gives you the ability to map, but also to remove or even add new items in the resulting mapped array. The same results of flatMap() can be achieved by using a map() followed by a flat() but using flat map is more efficient and provides for cleaner code.

REFRESH - How flat() works

The flat() method creates a new array with all sub-array elements concatenated into it recursively up to the specified depth. Let's look at an example of using the flat method.

const numberArray = [
1,2,[3,4,5],6,[[7,8],[8,9],[10,11,12]],13,[[14,15],[16,17]],[18]
];

Enter fullscreen mode Exit fullscreen mode

Using the flat() method on the above numberArray will create a new array by removing the nested arrays at a specified depth. The default depth is one level.

let flatArray = numberArray.flat();
console.log(flatArray);
Enter fullscreen mode Exit fullscreen mode

Running this code will provide the following RESULT =>

Image description

As you can see, we now have an array that no longer has nested arrays. There are however elements within the new array that are still arrays. These can be removed if we had run the flat() method at a depth of 2. See below.

let flatArray = numberArray.flat(2);
console.log(flatArray)
Enter fullscreen mode Exit fullscreen mode

Image description

We now have a flat array where each element is an individual number from the numbersArray!

REFRESH - How map() works

The map() method creates a new array from calling a function on every array element in the array that's called. There are a few important things to note about the map() method:

  • map() does not execute the function for an empty element.
  • map() does not change the original array.

Map is similar to forEach() however forEach() does not return anything and is affecting the original array. map() provides a new array built out of all the return values.

Here is an example of using the map() method:

let skiResorts = [
  "Meadows",
  "Crystal",
  "Big Sky",
  "Kicking Horse",
  "Jackson Hole",
  "Alta",
  "Park City",
  "Crested Butte",
  "Aspen"
];

let nameLengths = skiResorts.map(function (item, index, array) {
   return item.length;
});

console.log(nameLengths);
Enter fullscreen mode Exit fullscreen mode

In this example the map() method is being used to create an array of the length of each string within the skiResorts array. Here are the RESULTS =>

Image description

USING THE flatMap() METHOD

The following example will demonstrate how flatMap() can be a useful tool to non-destructively transform messy data into a usable format. Check out the following skiResorts array.

let skiResorts = [
  "Meadows",
  ["Crystal", "Stevens Pass"],
  "",
  "    ",
  "Park City,Deer Valley,  Canyons,  ",
  "Crested Butte, Aspen, A Basin",
  "Revelstoke",
  ["Kicking Horse", "Fernie", "Lake Louise"]
];
Enter fullscreen mode Exit fullscreen mode

A couple of things to notice:
-It is an array of ski resort names
-There are entries that are arrays of resort names
-There are empty entries
-There are entries that have a string of resort names separated by commas
-Spacing is inconsistent

The following steps will show how to compress this list where every entry in the array is a single ski resort.

Step 1

let resortsArr = skiResorts.flatMap((entry) => {
  if (Array.isArray(entry)) return entry;
});

console.log(resortsArr);
Enter fullscreen mode Exit fullscreen mode

In this function entry represents each line in the skiResorts array. The if statement is checking to see if each entry is an array and if true then return the array. Here are what the RESULTS look like=>

Image description

Notice that the entries within the skiResorts array that are not arrays are returned with undefined.

Step 2

This step will deal with the empty string entries by adding an else if condition to the conditional.

let resortsArr = skiResorts.flatMap((entry) => {
  if (Array.isArray(entry)) {
    return entry;
  } else if (typeof entry === "string" && entry.trim() === "") {
    return [];
  }
});
Enter fullscreen mode Exit fullscreen mode

Here the function is checking to see if each entry is both a string and empty, if true it will return an empty array. The reason to return an empty array is to allow for the removal of the empty arrays. Remember that this function is performing a map and then a flat. The map will return the same number of entries as the original array and then the flat will do a filtering and remove the empty arrays. Check out the RESULTS =>

Image description

Step 3

Tie to deal with the strings

let resortsArr = skiResorts.flatMap((entry) => {
  if (Array.isArray(entry)) {
    return entry;
  } else if (typeof entry === "string" && entry.trim() === "") {
    return [];
  } else {
    return entry.split(",");
  }
});

console.log(resortsArr);
Enter fullscreen mode Exit fullscreen mode

A final conditional has been added to the above function. entry.split will return the strings that have multiple resort names and turn them into arrays. See the RESULTS =>

Image description

This is close to our desired results however there are still some extra spaces that need to be taken care of.

Step 4

This is the final step. Take a look at what has been added to the resortArr function.

let resortsArr = skiResorts.flatMap((entry) => {
  if (Array.isArray(entry)) {
    return entry;
  } else if (typeof entry === "string" && entry.trim() === "") {
    return [];
  } else {
    return entry.split(",").map((txt) => txt.trim());
  }
});

console.log(resortsArr);
Enter fullscreen mode Exit fullscreen mode

Here a map has been added that uses the .trim() method to remove all the extra spaces in any of the entries within the array. Look at what the resortsArr looks like now. RESULTS =>

Image description

resortsArr is now an array where every entry is a single ski resort name (string).

CONCLUSION

flatMap() can be a very useful tool to efficiently and elegantly clean up data in a non-destructive manner.

Top comments (0)