DEV Community

Discussion on: Stop mutating in map, reduce and forEach

Collapse
 
redbar0n profile image
Magne • Edited

It seems like that last implementation using .reduce also violates the aforementioned purpose of reduce (since it returns an array, albeit a filter-mapped one): "reduce is about transforming a collection into a single value, that's why its param is called accumulator."

Collapse
 
smeijer profile image
Stephan Meijer • Edited

I'm not sure if you refer to the grouping example, or the alternative for filter.map? Anyways, I do mention that the return value doesn't always need to be a primitive.

But the return value doesn't always have to be a primitive. Grouping for example, is another very valid use case for reduce.

In that regard, I still see that snippet as a valid use case.

That being said. It doesn't perform better than the filter+map sequence. And it's also harder to read. So I wouldn't write it like that any more.

Is that section confusing? I rewrote it a bit after feedback and reconsideration, but decided to leave the filter/map vs reduce comparison in, so the comments would still make sense.

Collapse
 
redbar0n profile image
Magne • Edited

I was thinking about the filter+map example. But the grouping example is also a candidate.

The official docs say:

The reduce() method executes a reducer function (that you provide) on each element of the array, resulting in single output value.

developer.mozilla.org/en-US/docs/W...

It seems like an abuse to use .reduce in a way that treats an array or an object (containing two arrays) as "a single output value", especially when the examples in the official docs treats a single output value as either an accumulated sum, or one of the values in the original array.

I find clever tricks almost always more confusing than a more straightforward boring approach (like a for-loop or .forEach). In this case I agree that the filter+map is simplest.

I wouldn't consider the grouping to be a valid use case for ´.reduce´ either. Semantically speaking, it is more a case of filtering an array based on two conditions. Maybe this would be clearer to read:

const isEven = val => val % 2 === 0
const isOdd = val => val % 2 === 1
const ar = [1, 2, 3, 4, 5]
return {
 even: ar.filter(isEven),
 odd: ar.filter(isOdd),
}
Enter fullscreen mode Exit fullscreen mode

In general, I find it helpful to do one thing twice, than to do two things at once. It also follows the single responsibility principle for functions.

I would perhaps keep the sections in, but before every example just include an Update: Due to insightful comments, I no longer recommend this approach:.

Thanks for your post, and for your thoroughness in following up!