DEV Community

Phillip Kent Knight
Phillip Kent Knight

Posted on

I spent an entire Saturday trying to understand .reduce()

Lately, I've been trying to up my js skills… including a run through some Javascript courses on Codecademy, which I was totally crushing until I got to reduce()… 🤯!!

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

That description did nothing for me.

I had no problem working through and understanding other array handling methods like filter() and map()... but I hit a roadblock trying to grasp what reduce was all about. And I spent an entire day on it.

But now, I think I finally get it: we "reduce" an array of objects into one object by performing a function on each item in an array, saving the result at each step to an accumulator. It's kind of like the way we use a for loop, but here we're adding to (accumulating) just one result.

This "accumulator" thing, as I now imagine it:
Animation of accumulator value: a + b = ab, ab + c = abc, and onward through an array of the English alphabet

If that doesn't help, here are the examples I wrote for myself to make sure I understood the basic nature of the accumulator.

How I got here

To get to this level of understanding, I had to look at MDN, blogs, youtube, and finally give up and ask a more experienced programmer (my friend Dave) to explain it to me like I was five.

This was what I got as an example:

While I now understand what's going on above, I didn't when I first saw it.

The resources that clicked for me

Finally, after several hours, I started to get it somewhere around my third read of Jason Belcher's post: "Map, Filter, and Reduce", which actually demonstrates rolling your own reduce-like function, and my second watch of the below video from The Coding Train on YouTube.

If you've made it this far down the page, you might be as frustrated and confused (and determined) as I was - I hope these links will help you like they did for me me!

Top comments (6)

Collapse
 
bbarbour profile image
Brian Barbour

I think reduce is a weird verb for the method, but thanks for writing this up. Def helped me with a quick way to remember what it means/does.

Collapse
 
phillipkent profile image
Phillip Kent Knight

I agree... but I guess ".conglomerate()" would be too long...

Collapse
 
bbarbour profile image
Brian Barbour

yeah I sat here for 10 minutes trying to think of a better name. Couldn't. So reduce it is! haha

Thread Thread
 
earthtone profile image
Tonio Hubilla

It's sometimes called fold in other languages.

Reduce is probably my favorite list operation, but it took me quite a while to really grok it and feel comfortable using it as often as I do now.

Two important things I noticed about your friend's example that helped me in the beginning are his use of an optional argument - i for the parent array's index - and his explicit assigning of an initial value - ''.

Optional arguments, like index aren't traditionally included in other implementations of reduce, and it's something specific to JavaScript's implementation on Array. I found it super useful as I was starting to learn, but eventually you build up a confidence with writing "pure" reducers.

Setting initial values for your accumulator is a great sanity guard, and communicates what type of elements your reducer can work with. For example, if you have an array that is a mix of numbers and strings, setting an initial value will remind how to "cast" or "coerce" your elements...

const unsafelyConcatenateAll = [0, 'x', 3, 'z'].reduce((a, c) => a + c.toUpperCase()) // -> TypeError: c.toUpperCase is not a function

const safelyConcatenateAll = [0, 'x', 3, 'z'].reduce((a, c) => a + String(c).toUpperCase(), '') // -> "0X3Z"

JavaScript actually sets your accumulator's initial value as the first index of the parent array if none is given. So unsafelyConcatenateAll fails because the initial value is a Number not a String. There's a ton of other useful things about explicitly setting your initial value, but in my experience the most important is that it communicates to other people (including future self) "Hey, don't try to do math on strings!" or whatever the case may be

Most of this probably doesn't mean much to you yet, but learning to love reduce was the beginning of my journey down the Functional Programming rabbit hole I'm still falling down today. If you had fun learning about reduce, map, filter and other list operations, I'd highly recommend Kyle Simpson's Functional Light JS book for a clear, no-nonsense, practical background on the theoretical stuff.

Thread Thread
 
phillipkent profile image
Phillip Kent Knight

This is a great explanation and makes perfect sense to me - my original post was mostly driven by failing to properly imagine/visualize the accumulator itself, but it's definitely helpful to have a clearer understanding of the use cases for initial value and index.

Collapse
 
toanbku profile image
Ho Quang Toan

Nice post, thank you :))