DEV Community

Cover image for An Alternative to filter().map(): Using flatMap()
Raja Jaganathan
Raja Jaganathan

Posted on • Edited on

13 1 1

An Alternative to filter().map(): Using flatMap()

When working with arrays, developers often use Array.filter().map() to transform data. But did you know Array.flatMap() can achieve the same result in a single step? Let’s explore when to use each.

Old Approach with 2 iteration: filter().map()

const persons = [
  { name: "Raja", age: 36 },
  { name: "Jaganathan", age: 65 },
  { name: "Kumar", age: 50 }
];

const result = persons.filter(p => p.age > 60).map(p => p.name);
console.log(result); // ["Jaganathan"]
Enter fullscreen mode Exit fullscreen mode

Here, .filter() first selects the matching objects, and then .map() extracts names. Though it involves two loops, modern JavaScript engines optimize it well, making it faster in many cases.

New Approach with 1 iteration: flatMap()

const result = persons.flatMap(({ age, name }) => age > 60 ? name : []);
console.log(result); // ["Jaganathan"]
Enter fullscreen mode Exit fullscreen mode

With flatMap(), we combine filtering and mapping in one pass, making the code more concise. However, performance may slightly drop because flatMap() internally flattens arrays, adding overhead.

Performance Comparison

Multiple approaches have been tested on jsperf.app. Thanks @miketalbot and @webjose.

🔹 flatMap() vs filter().map() – There’s no clear winner, but flatMap() shows a slight performance advantage in some cases.

When to Use Each

✅ Use filter().map() when clarity and semantic intent are important.
✅ Use flatMap() when reducing iterations and simplifying code structure matters more than micro-optimizations.

Happy Coding! 😊

SurveyJS custom survey software

Simplify data collection in your JS app with a fully integrated form management platform. Includes support for custom question types, skip logic, integrated CCS editor, PDF export, real-time analytics & more. Integrates with any backend system, giving you full control over your data and no user limits.

Learn more

Top comments (13)

Collapse
 
miketalbot profile image
Mike Talbot ⭐ • Edited

Is it more readable though? I'm not sure about that.

Anyway, flatMap can be made to perform faster than .filter then .map if you are more careful with the array construction:

  • You don't need to wrap name in an array
  • You can use a single predefined dummy array in the empty result
const filter_out = []

persons.flatMap(({ age, name }) => age > 60 ? name : filter_out);
Enter fullscreen mode Exit fullscreen mode

Doing this improves the performance, so it becomes the fastest method. However, flatMap does not tell me you are doing a filter and a map; it tells me you are dealing with arrays of arrays, so I find the intent of the code requires significant parsing, which is probably not worth the 5% speed improvement.

Performance results: jsperf.app/baxase

Collapse
 
webjose profile image
José Pablo Ramírez Vargas

Even more tests: Version 3

This one demonstrates that the encapsulation of code is rather costly. If this were C++ or a similar language, this would be an indication that the function needs to be inlined.

Anyway, this was fun. Thanks, Mike! I learned about this performance website because of your insightful comment.

Collapse
 
miketalbot profile image
Mike Talbot ⭐

Wow, yeah, that's the thing isn't it - 2x the speed if we just use a normal loop... That shocked me, so I tried it with an iterator loop rather than a for...of, and there's a new winner (for which I'm slightly shocked)!!!

Version 4

Thread Thread
 
miketalbot profile image
Mike Talbot ⭐

Also, damn good point about the encapsulation, that is odd...

Thread Thread
 
webjose profile image
José Pablo Ramírez Vargas • Edited

Ok, this is fun.

Version 5

I have encapsulated the code in a reusable function as before, only with the winner that iterates over the index of the array.

Look at the differences. Here's a screenshot ran in MS Edge v133:

Image description

Label #1 is the fastest one, your proposal using the iterator, then there's #2 which is the original encapsulated one. 45% slower. Damn!! But #3 is the iterator version encapsulated and is only 5 or 8% slower. This tells me that there's something wrong in Chromium. It doesn't have much sense to me such big difference. But what do I know.

Anyway, notice how there might be a difference between using ++i and i++. In C/C++, overloading this operator tellls you something very interesting: ++i is more performant (in C++) because i++ has to create a copy of itself to be used as return value. It might be true for JavaScript too.

Thread Thread
 
miketalbot profile image
Mike Talbot ⭐

Wow, that is fascinating... You're right, some very unexpected behaviour that...

Collapse
 
webjose profile image
José Pablo Ramírez Vargas • Edited

As always, Mike making sense. Thanks for the insightful post.

I made an edition to your performance test because I think we should never lose sight of what plain JS can do: Version 2 of performance tests

As expected, plain JS beats them all.

Collapse
 
rajajaganathan profile image
Raja Jaganathan • Edited

Agreed flatMap has different purpose and semantic too. just illustrate for different use case.I miss the point of the unwanted array creation.

Collapse
 
sathyamoorthi_p_65361ee6d profile image
Sathyamoorthi P • Edited

This will be much simpler for readability

const filter = [];
persons.flatMap(obj => (obj.age > 60) ? obj.name : filter);
Enter fullscreen mode Exit fullscreen mode
Collapse
 
elijahmanor profile image
npm i elijahmanor

Nice post. Another alternative would be reduce, however it is questionable on how readable it is in comparison :)

jsperf.app/baxase/6

Collapse
 
sathyamoorthi_p_65361ee6d profile image
Sathyamoorthi P

Good one Raja. Thx for introducing a new method with detailed performance reasoning.

Collapse
 
leob profile image
leob

More readable? Not at all, IMO ...

Chaining steps is the essence of this approach, and "filter" followed by "map" expresses that approach and that thought process much more clearly ...

Collapse
 
buecui_salos_72b647d8f62f profile image
Buecui Salos

Array.flatMap() is a great alternative to filter().map() for simplifying code by combining filtering and mapping into one iteration. While filter().map() is clear and easy to understand, flatMap() can be more concise and reduce iterations. However, flatMap() can introduce slight performance overhead due to internal array flattening. Use filter().map() when clarity matters and flatMap() for optimizing iterations.

Also, for those in Riyadh, remember to check the Salah times!

The Most Contextual AI Development Assistant

Pieces.app image

Our centralized storage agent works on-device, unifying various developer tools to proactively capture and enrich useful materials, streamline collaboration, and solve complex problems through a contextual understanding of your unique workflow.

👥 Ideal for solo developers, teams, and cross-company projects

Learn more