DEV Community

loading...

Discussion on: What´s wrong with Array.reduce ?

Collapse
costinmanda profile image
Costin Manda

I like this approach (plus I finally understood where reducer comes from :D - in .NET it's called Aggregate). However, I also think that if one is not going to (re)use multiple types of reducers, there is no need to use reduce to emulate a forEach or even a normal loop.

But congratulations on the conciseness of your code!

Thread Thread
wulymammoth profile image
David

Yeap! I've never done C#, but the analogs are listed in this SO thread: stackoverflow.com/questions/428798...

Yeah, it was a contrived example from many people in this thread. I also don't use JS regularly at all anymore which is why I often default to ES5 syntax.

I typically end up using reduce for "partitioning" or performing only a single iteration through the collection to include/exclude/filter into a different data type, like a set, map, etc to keep things atomic... we've all seen people declare combination of multiple arrays, array and object, array and map, etc at the TOP of the file and the actual for-loop is modifying it 100 lines down, and some other code that modifies it in between... that's really really really bad and shitty for anyone needing to debug it. These functional facilities over collections make them atomic and you know where to look if there's a bug -- the reducer (hopefully unit-tested)...

I've used reduce for a lot of this (changing data-types, and accumulation to a different collection type)

let numStrings = ['1', '2', '3'];
numStrings.reduce((map, num) => {
  const num = parseInt(num);
  return num % 2 === 0 ? map.evens.push(num) : map.odds.push(num);
}, {evens: [], odds: []});

// RESULT (strings are converted to integers in a nice map/object of evens and odds)
// {evens: [2], odds: [1, 3]}

Some people call this "partitioning". The above would be difficult to express with just a filter call or for-loop without scattering variables. The thing that gets most people is where the "initial value" {evens: [], odds: []} is. People are just very used to seeing it right above an iteration

Thread Thread
costinmanda profile image
Costin Manda

I see what you are saying, but unless you are going to reduce that function, this can just as well be expressed by a forEach or a loop. One declaration of a variable above it doesn't bother me. Cheers!

Thread Thread
wulymammoth profile image
David

forEach just abstracts away the iterator variable boilerplate, but could still leave the collection variables scattered about, like at the top of the file and make it possible for someone to mutate them in between... but yah!

Thread Thread
icyjoseph profile image
Joseph

Pardon for jumping in but fold are very well studied functions, as you know :) Sorry for dropping a link, but it speaks much better than I could: Fold Higher Order Function

Thread Thread
tech6hutch profile image
Hutch

@wulymammoth your code is slightly wrong. You have to return the accumulator (the object of arrays, this case). You're instead returning whatever push returns (which is the length of the array after pushing). (Also, you're re-declaring the parameter num as a const, which isn't allowed, but that's a simpler fix.)

Thread Thread
wulymammoth profile image
David

All good catches