DEV Community

Discussion on: filter, map and reduce in JS. When and Where to use??

Collapse
lukeshiru profile image
LUKESHIRU • Edited on

Array.prototype.reduce should be used mainly for sums or products, not so much for mapping as you did. Your reduce example could be just:

users
    .filter(({ birthYear }) => birthYear !== null && currentYear - birthYear > 25)
    .map(({ name }) => name);
Enter fullscreen mode Exit fullscreen mode

No need for reduce, there. The performance difference is dismissible if the readability is better (which is always better if you avoid reduce), and if your actual concern is performance, then you should use forEach or even just a for.

Cheers!

Collapse
nehal_mahida profile image
Nehal Mahida Author

Definitely a good point 👏🏻

Performance vs readability is a never-ending debate.

I intend how we can avoid two methods by just using reduce and explaining to the people how to use reduce syntactically!!

And yes, for loop is there to achieve all of these things.

Collapse
lukeshiru profile image
LUKESHIRU

You can explain reduce with a sum and is clear enough:

const numbers = [1, 2, 3];
numbers.reduce((total, number) => total + number, 0); // 6
Enter fullscreen mode Exit fullscreen mode
Collapse
captainyossarian profile image
yossarian • Edited on

You will get noticeable performance hit if your array has more than 1K elements. In worst case scenario you will iterate 2 times over 1K elements. Btw, what makes you think that reducer is not readable?

type User = {
  name: string;
  city: string;
  birthYear: number;
}
declare const users: User[]

const currentYear = new Date().getFullYear();

const olderThan25 = (user: User) =>
  user.birthYear && (currentYear - user.birthYear) > 25 ? [user] : []

const getName = ({ name }: User) => name

const userNames = users.reduce((acc, user) =>
  olderThan25(user)
    ? acc.concat(getName(user))
    : acc,
  [] as Array<User['name']>
);
Enter fullscreen mode Exit fullscreen mode

You can chain map and filter in functional languages, like for example F# because there is no intermediate value.

Collapse
nehal_mahida profile image
Nehal Mahida Author

That's a good point with a great code presentation. 👍🏻

Collapse
lukeshiru profile image
LUKESHIRU

I mean, I tried with 40.000 elements and is still not a huge gap. Browsers nowadays have lots of optimizations for this kind of operations. And idk about you, but I still believe that array.filter(olderThan25).map(getName) is more readable than array.reduce((acc, user) => olderThan25(user) ? acc.concat(getName(user)) : acc) X_X

Thread Thread
uuykay profile image
William Kuang

Performing map, then filter is 2 iterations of the list. Despite some small readability gains, the performance loss is just too great.

Thread Thread
lukeshiru profile image
LUKESHIRU

"performance loss is too great" ... have you actually ran the code above? Browsers optimize those kind of chained operations. The performance difference might br noticeable maybe with, idk, 100k items, but if you have to filter/map that amount of items, your problem is elsewhere.....