Skip to Content
Course content

45: Array Methods: flat and flatMap

Click on the "Edit" button in the top corner of the screen to edit your slide content.

You’ve probably run into this a dozen times: you fetch some data from an API, and instead of a clean list, you get a list of lists. Maybe it's a list of users, and each user has a list of tags. If you need a unique master list of every tag used across your entire platform, you're suddenly staring at a nested array that doesn't do you any good in its current state.

The struggle with reduce and concat

Before flat() was added to the language, I used to see people (including myself) lean heavily on reduce(). The logic usually looked something like this:

const userTags = [
  ['javascript', 'webdev'],
  ['react', 'javascript', 'frontend'],
  ['node', 'backend']
];

const flattened = userTags.reduce((acc, current) => {
  return acc.concat(current);
}, []);

Now, this works. It's logically sound. But it's a bit of a chore to write, and more importantly, it's inefficient. Every time concat() is called, JavaScript creates a brand new array and copies the elements over. If you're dealing with a massive dataset, you're essentially forcing the engine to do a huge amount of unnecessary memory allocation. It's a classic case of "it works on my machine" until the production data hits a certain scale and the performance dips.

Cleaning up the noise with flat

This is exactly why flat() exists. It does one thing: it collapses nested arrays into a new array. No more reduce boilerplate.

const flattened = userTags.flat();

One thing to keep in mind is that flat() only goes one level deep by default. If you've got an array that's nested three or four levels deep—which usually means your data structure is a mess, but it happens—you can pass a depth argument. I've occasionally used flat(Infinity) when I had no idea how deep the nesting went and just wanted everything on one level. Just be careful; flattening a massive, deeply nested structure can be expensive, so use Infinity sparingly.

When mapping and flattening collide

The real magic happens when you need to transform the data and flatten it at the same time. Imagine we have a list of orders, and each order has an array of line items. We want a single list of all the product IDs sold.

The "naive" modern way would be to chain map() and flat():

const orders = [
  { id: 1, items: [{ productId: 'A1' }, { productId: 'B2' }] },
  { id: 2, items: [{ productId: 'C3' }] },
  { id: 3, items: [{ productId: 'A1' }, { productId: 'D4' }] },
];

const productIds = orders.map(order => order.items.map(item => item.productId)).flat();

That works, but it's clunky. You're iterating over the data to map it, creating a nested array, and then iterating over it again to flatten it. This is where flatMap() comes in. It combines both steps into a single pass.

const productIds = orders.flatMap(order => 
  order.items.map(item => item.productId)
);

I always reach for flatMap() in this scenario because it's cleaner to read and slightly more performant. It's basically saying: "Transform each element into an array, then flatten the result by one level." It's a powerful pattern, especially when you need to filter items out as well—since flatMap() allows you to return an empty array [] to effectively remove an item from the final result, something a standard map() can't do.




📋 Practical Task

Extracting a Master Playlist from Nested Albums

You are building a music library app. You have an array of album objects, and each album has an array of song objects. Your goal is to create a single, flat array containing only the titles of all songs across all albums, but only for songs that are longer than 3 minutes (180 seconds).

Initial Data:

const library = [
  {
    album: "Greatest Hits",
    songs: [
      { title: "Song A", duration: 200 },
      { title: "Song B", duration: 150 },
    ]
  },
  {
    album: "Deep Cuts",
    songs: [
      { title: "Song C", duration: 210 },
      { title: "Song D", duration: 120 },
      { title: "Song E", duration: 300 },
    ]
  }
];

Your Task: Use flatMap() to generate a flat array of strings (the titles) for all songs that meet the duration criteria. Your final result should be ["Song A", "Song C", "Song E"].

Rating
0 0

There are no comments for now.

to be the first to leave a comment.