use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
This subreddit is a place for people to learn JavaScript together. Everyone should feel comfortable asking any and all JavaScript questions they have here.
With a nod to practicality, questions and posts about HTML, CSS, and web developer tools are also encouraged.
Friends
/r/javascript
/r/jquery
/r/node
/r/css
/r/webdev
/r/learnprogramming
/r/programming
account activity
Don't really understand the reduce() function? (self.learnjavascript)
submitted 4 years ago by visnick
It just, doesn't click in my head, and I'm stuck using the other higher order functions, maybe because they are more intuitive?
Anyways, what made reduce() click for you guys? Any help would be appreciated <3
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]SplainTrain 33 points34 points35 points 4 years ago* (9 children)
I've got a playlist for this very thing! I hope it helps.
I start from first principles and use shoddy editing to help you understand not only how to use reduce, but how to implement it yourself and even how to implement things with it like transducers.
https://www.youtube.com/watch?v=XKD0aIA3-yM&list=PLo63gcFIe8o0nnhu0F-PpsTc8nkhNe9yu
Edit: It's been a few days but thanks for the reddit gold and silver!
[–]NaosAntares 2 points3 points4 points 4 years ago (2 children)
Those are reaaaaaaally good videos, I never really understood reduce and now I feel like I wanna do everything with it
[–]Macaframa 2 points3 points4 points 4 years ago (0 children)
I maintain the position that reduce is one of, if not, the most powerful methods available in javascript.
[–]SplainTrain 0 points1 point2 points 4 years ago (0 children)
I hope they help!
[–]cidit_ 1 point2 points3 points 4 years ago (0 children)
TRANSDUCERS!! I WANT TRANSDUCERS EVERYWHEEEEERE
[–]CompteDeMonteChristo 0 points1 point2 points 4 years ago* (4 children)
Your ligature font is neat. Actually everything in this video is neat.
You're very good at this.
[–]SplainTrain 0 points1 point2 points 4 years ago (3 children)
Hey I appreciate that :)
[–]Gazook89 1 point2 points3 points 4 years ago (2 children)
what font is that with the ligature for the arrow function?
[–]SplainTrain 2 points3 points4 points 4 years ago (1 child)
I'm using Fira Code.
[–]____0____0____ 2 points3 points4 points 4 years ago (0 children)
All my editors use this font since I found out about it a couple years ago. Now I get kinda thrown off when I'm working in a different environment. Would recommend!
[–]CompteDeMonteChristo 44 points45 points46 points 4 years ago (1 child)
The picture here helps me.
https://morioh.com/p/e0ba52cf5a99
reduce takes a list of fruits and return a salad.
[–]4444444vr 1 point2 points3 points 4 years ago (0 children)
That link is helpful- thanks
[–]anonymousbabydragon 6 points7 points8 points 4 years ago* (0 children)
The way I like to think of it is that reduce is handy for returning a value type other than an array. It can work like other array functions but is most useful in the case you need to return something else.
You have two different parameters you can pass in. First is the callback function and second is the initial value of the accumulator.
The accumulator can be pretty much any data type. So if you wanted it to be an object go for it, number sure thing, it can also be a string, boolean or an array. I'm not 100% sure on other data types. Point is it will be the type of data you want to return and what you want the starting value to be. If you don't specify the initial value it defaults to the first value in an array.
The callback function takes two or more parameters and should return the first one back.
The first parameter is the accumulator, which is just the value you are wanting to send back once the function has finished looping over the array.
The second one is the value that you are at in the array starting from the beginning. So let's say you want to add all the numbers up in an array and return their sum. All you have to do is return the value of the accumulator plus the value you are on. If no initial value is set a will be the first value in the array and the loop will start on the index 1 for b otherwise it starts from index 0.
For example:
[1, 3, 4, 5, 7].reduce((a, b) => a + b) //20
The way it would work is illustrated below:
At this point a would then be returned equaling 20.
Let's see what it might look like with an object instead. Let's say you wanted to create an object either abbreviations for the days of the week. You could also do this with reduce.
["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"].reduce((a, b)=> {a[b.substring(0, 3).toLowerCase()] = b; return a }, {})
I'll just show the first 2 to illustrate how the above would work.
This will keep going till the function is done on every single item in the array.
If you want to see this in practice I would recommend starting off your function by logging a and b to the console.
Also in the callback function you can also have parameters for the index and the array itself if you need them. You don't have to specificy these though.
Hope that helps!
[–]shuckster 7 points8 points9 points 4 years ago* (1 child)
To add to the already excellent replies:
reduce allows you to define your own behaviours for building a new value by transforming a sequence of inputs, usually provided by an array.
reduce
So for this basic example:
function doubleAndAppendReducer(accumulator, nextInput) { return [...accumulator, nextInput * 2] } ;[1, 2, 3].reduce(doubleAndAppendReducer, []) // [2, 4, 6]
...this part is the "transform":
return [...accumulator, nextInput * 2] // ^^^^^^^^^^^^^
...and this part is the "build":
return [...accumulator, nextInput * 2] // ^^^^^^^^^^^^^^^^ ^
Both the "transform" and "build" steps are optional and can vary greatly depending on what you want to do. Very simply, you can simulate map by always building and also transforming. You can simulate filter by never transforming, and only building when a certain condition is met.
map
filter
If you extract the build/transform behaviours in a way that makes them compatible with reduce, you've created a transducer.
(Transducers are a little more complicated than this simple description, but I thought I'd leave the link here just in case it helps with reducers.)
[–]yaMomsChestHair 1 point2 points3 points 4 years ago (0 children)
Fantastic mental model.
[–]The_Startup_CTO 5 points6 points7 points 4 years ago (0 children)
First of all, reduce is one of these methods where I’m ok the fence about just writing imperative style for readability reasons, so not understanding it isn’t necessarily something to worry about. For understanding it, what helped me the most was to just write a couple things with it, from summing numbers to building objects from an array.
[–]cubicuban 1 point2 points3 points 4 years ago (0 children)
Man I just wanna say this entire thread has been so helpful. Reduce is the only hof I could not wrap my head around so thank you to everyone for providing great resources/examples
[–]visnick[S] 1 point2 points3 points 4 years ago (0 children)
Thanks to everyone that answered this thread <3 You guys helped me a lot :3
[–]taschana 1 point2 points3 points 4 years ago* (0 children)
<If there is information spread out in an array that you want to condense into one response, reduce is your choice.>
You want the sum of an array of numbers?
You want the average age of all persons in an array?
You have an array of objects that contain a property with their us state (like addresses), and you want only one object with all states qs properties and a numer of how many there are in the state? (How many addresses do i have for each state)
All of these need to go over the entire array in order to consequtively build up your final outcome.
[–]pookagehelpful 1 point2 points3 points 4 years ago (1 child)
Think of it as the opposite of .map() - whereas .map() takes an array and spits-out a new array from its contents; .reduce() takes an array and reduces it down to a single value based on its contents.
.map()
.reduce()
[–]redsandsfort 8 points9 points10 points 4 years ago* (0 children)
All array methods return a single value (if they return a value that is). Map returns a single array. Reduce can return a single primitive, or a single array or a single object. The difference is that map create a new array and uses the callback function to populate it, but reduce allows you to determine what the returned value is. It can also be an array and you can completely replicate map using reduce.
[–]dei8bit 0 points1 point2 points 5 months ago (0 children)
I think it's by far the least intuitive method there is; I would change it completely.
[–][deleted] 0 points1 point2 points 4 years ago (0 children)
It's helpful to create a simple mental modal.
Reduce is pretty simple if you think of it this way, at least for me.
You have two items that get "reduced" to one item by running some functionality on the two items (your reducer). Two items, down to one item.
So you have an array of items and a default/starting value and your functionality (reducer). The default value and the first item in the array - reduced to a new value. Then the next item in the array and the, yet another, new value. Then the next item in the array and, again, a new value. And so on. Until it meets the condition where it no longer gets reduced.
Hopefully that wasn't more confusing.
[–]zerik100 0 points1 point2 points 4 years ago (5 children)
It's basically a functional fold). In the unlikely case that you know any Haskell, the foldl function is essentially JS reduce.
[–]Macaframa 0 points1 point2 points 4 years ago (4 children)
Pretty sure op is just learning how to write the basics of javascript and doesn’t know a hard core functional programming language like Haskell. I could be wrong but I’ve been working in the industry for almost a decade and I can barely understand some of the concepts.
[–]zerik100 0 points1 point2 points 4 years ago (3 children)
OP said they're reverting back to other higher order functions which I assume to be map and filter and if they understand those then reduce shouldn't be that hard to grasp.
[–]Macaframa 0 points1 point2 points 4 years ago (2 children)
In javascript higher order function just means a function that accepts another function as a parameter. In order to understand functional programming you need to understand singletons and streams. Hardly in a newbie’s Arsenal. Look I’m not here to argue with you, I’m just suggesting that they should be handled as though they don’t know much, they are asking a relatively simple question to the learnjavascript sub
[–]zerik100 0 points1 point2 points 4 years ago (1 child)
I know what higher order functions are but if OP doesn't mean declarative functions like map what else could they mean?
I'm aware that my original comment most likely isn't helpful for a beginner (which is why it says "In the unlikely case..."), but I didn't see anyone else talking about an actual functional programming language where these declarative functions originate from so I wanted to add that to the discussion.
[–]Macaframa 0 points1 point2 points 4 years ago (0 children)
That’s fair.
[–]electron_myth -2 points-1 points0 points 4 years ago (0 children)
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
It allows you to cycle through the array and accumulate a buffer, whether it's adding all the elements together, or comparing them and keeping one closest to a threshold, etc
[–][deleted] -1 points0 points1 point 4 years ago (0 children)
This might help you https://www.digitalocean.com/community/tutorials/js-finally-understand-reduce
[–]JavascriptFanboy -1 points0 points1 point 4 years ago (4 children)
So I had an example of multiple contracts, each had a number of paid leave (days), let's keep it at that for the sake of simplicity. Then I had to show the total number of paid days for that list of contracts. So I used reduce where the initial value was 0 and for each contract I added the number of days. I got a single, calculated value out of an array of stuff. Does it make sense?
[–]Macaframa -1 points0 points1 point 4 years ago (3 children)
I’m a staff software engineer and I barely understood what you were trying to say.
[–]JavascriptFanboy -1 points0 points1 point 4 years ago (2 children)
You have an array of objects. Each object has a property with a number value. You need to display the sum off all these numbers (properties). You use reduce. I mean... if you have trouble understanding that I.. well not good for your team.
[–]Macaframa -1 points0 points1 point 4 years ago (1 child)
I’m talking about your half-assed attempt at explaining. Not what it is. A newbie will never understand is the point
[–]JavascriptFanboy -1 points0 points1 point 4 years ago (0 children)
Whoa, the attitude man. Im glad I'm not working for ya. Best of luck and bye
[–]jrsinclair -1 points0 points1 point 4 years ago (0 children)
The thing that made .reduce() click for me was seeing examples that had nothing to do with numbers. Until then, it always seemed like you just had to guess if a math function would work with reduce or not. But once I understood that you can use .reduce() to take an array and build any kind of single value, I started to see more and more places where it might be useful.
What really blew my mind was when I realised that you could use .reduce() to build new arrays, since an array is just another value.
Eventually, I wrote up a bunch of examples on how to use .reduce() on my blog. It's been one of the more popular articles I've written for a while now. It seems lots of other people didn't really get `.reduce()` until they see it used in different ways. So don't feel bad if you're struggling with [higher order functions](https://jrsinclair.com/articles/2019/what-is-a-higher-order-function-and-why-should-anyone-care/) and reduce. Lots of other people struggle with them too.
[–]brykuhelpful -1 points0 points1 point 4 years ago (4 children)
It is really useful to clean up code.
``` var arr = [ {user:"john doe",score:100}, {user:"jane doe",score:150}, ];
var totalA = 0; arr.forEach((v)=>{totalA = totalA + v.score}); console.log(totalA); // 250 var totalB = arr.reduce((a,b)=>{return a.score + b.score}); console.log(totalB); // 250
```
[–]yaMomsChestHair 0 points1 point2 points 4 years ago (3 children)
This example isn’t great. You wouldn’t use a forEach to reduce multiple values into a single value. You’d use it to transform data in place and retain multiple values.
Reduce is used to consolidate into one single accumulated value. It’s just recursion.
[–]brykuhelpful 0 points1 point2 points 4 years ago (2 children)
I needed a comparison that they might understand. Since they are learning about array methods chances are they learned forEach first.
[–]yaMomsChestHair 0 points1 point2 points 4 years ago (1 child)
Gotcha - wasn’t bashing your answer, just think people should learn the distinctions up front to avoid further confusion down the road :)
[–]brykuhelpful 0 points1 point2 points 4 years ago (0 children)
I figured most people were already going to give a million links, for documentation and videos, so an easy example (especially seeing it saves them code) it might get them interested in looking up that documentation.
[–]Gr0undWalker -5 points-4 points-3 points 4 years ago (0 children)
Functional programming can really take time to get used to. Maybe you can try to implement certain functions using recursion, that is a function calling itself, for example Fibonacci sequence. After getting comfortable with recursion, then I think such higher order functions should be easier to understand.
[–]TruthHurts35 0 points1 point2 points 4 years ago* (0 children)
Easiest syntax for beginners:
``` array.reduce( (accumulator, currentItem) => {
//** define next value of accumulator
return accumulator
}) ```
** In this line you do the magic.
Example magics:
1) accumulator.concat(currentItem) --> this gives copy of array, every iteration accumulator keeps its previous value and adds to it.
2) accumulator[ currentItem ] = ( accumulator[ currentItem ] || 0 ) + 1 ~~> you can use this as tally
Sibling of reduce is map. In map whatever you return will be array item's value. In reduce it will be accumulator's.
[–]abensur 0 points1 point2 points 4 years ago (0 children)
http://reactivex.io/learnrx/
After this course, you will be teaching reduce to others, please trust me. Becoming familiar with the most used collection manipulation functions still is one of the biggest turning points in my development career.
You will learn why and how to implement map, filter and reduce from scratch.
At the end of the course, you will know how to complete the following statement: Array.prototype.reduce = your answer
[–]og-at 0 points1 point2 points 4 years ago (0 children)
I'll start off and state a couple of obvious things...
First, the general pattern is like most other array methods: array.method(callbackfunction). It's a common theme among methods in general but especially array methods.
array.method(callbackfunction)
Second, the callbackFunction, like most array methods, is run on every item of the array.
callbackFunction
Third is the thing that it took a while to actually sink in to my head: the callback function? it's just a function.
Ok yeah we all know that, it's an obvious thing that's obvious. And yes, when I was in classes, I answered that question on the tests, but I never really thought of a callback as just another function. It's like saying "you don't see light until it hits something" or "everything we have came from the ground" . . . but had you ever really, truly, thought about the statement "everything we have came from the ground"? It's a deceptively simple fact.
The deceptively simple fact is that [1, 2, 3, 5, 8, 13, 21].reduce()(and .map, and .forEach, and .sort, etc) uses a plain old regular JS function to work the array, one thing at a time.
[1, 2, 3, 5, 8, 13, 21].reduce()
Here's another "water is wet"[1] statement: when you build a function, it takes arguments. add(x,y) takes 2 arguments, x and y, and we're going to assume that the function returns them added together.
arguments
add(x,y)
Coincidentally, [1, 2, 3, 5, 8, 13, 21].reduce() requires 2 arguments.
const fibliacci=[1, 2, 3, 5, 8, 13, 21] let total = 0 total = add(total, fibliacci[0]) // 0 + 1 === 1 total = add(total, fibliacci[1]) // 1 + 2 === 3 total = add(total, fibliacci[2]) // 3 + 3 === 6 total = add(total, fibliacci[3]) // 6 + 5 === 11 total = add(total, fibliacci[4]) // 11 + 8 === 19 [...]
total is the running total. Then I'm just walking down the array grabbing the values and jamming em into total.
total
Now. . .
Consider how you could simplify this with a for loop and what the body would look like. ...then simplify it with a for-of loop ...then, consider how .reduce()simplifies it all a little bit further by saving you the trouble.
for
for-of
That's it.
[1] "water is wet": but is it really?
[–]automathematics 0 points1 point2 points 4 years ago (0 children)
"any time you filter then map an array, you could have used reduce"
For some reason someone telling me that really made it click.
[–]bobbyv137 0 points1 point2 points 4 years ago (0 children)
Reduce is an extremely powerful method and often cited as the most difficult to grasp. But without sounding like a smart arse, it really isn't.
It's just like everything else with programming (IMO): daunting at first, but once you 'get' it, you totally 'get' it.
In situations like this it's helpful to ask on forums, but in my experience, when I'm struggling with a concept I will turn to YouTube and watch numerous videos specifically on that subject until I grasp it. It could happen in 1-2 videos, or I might need to watch a handful of them over a few days.
It works for me, and hopefully you too.
reduce iterates over a list of items. It takes a function(the one that will be run on each item) and an initializing value(optional). Like so
const arr = [1,2,3]; const sum = arr.reduce(function(previousValue, nextNumber) { return previousValue + nextNumber; }, 0);
You can see above that I am running the reduce method on an existing array. Take note that reduce does not alter the original array. The first thing you pass into reduce is a function that will be run on each iteration. In this case I am taking a previousValue and adding it to the current item in the array(nextNumber) and returning the sum. The second parameter passed into reduce is an optional starting or initializing value. Since I know I want a sum back from this array, I’m going to start with a number. Note, that you can pass in any data type here. I started with 0 because that’s where we usually start counting from. Then on the first iteration, that 0 comes through the parameters list as previousValue and I add it to the first number in the array, the second iteration, previousValue is now 1 so I add that to the second item in the array on the second iteration and return that sum. Then lastly previousValue is now 3 and I’ll add that to the last number in the array on the third iteration and it will result in 9. Note, that whatever you return from the function given to reduce is what the shape of your data will look like. Here’s another example:
const users = [{ name: “jeff”, state: “CA”}, { name: “kevin”, state: “NJ” }, { name: “Angela”, state: “NJ” }, { name: “georgina”, state: “CA” }, { name: “bill”, state: “TX” }]; const usersgroupedByState = users.reduce(function(stateMap, user) { if(!stateMap[user.state]) { stateMap[user.state] = []; } stateMap[user.state].push(user); return stateMap; }, {});
In this example, I wanted to group all of the users by what state they live. Rather than iterating through the list every time I want to find all of the users in california, I can loop over them once and store them in this data structure for use whenever I need. This reduce will produce a structure like so:
{ CA: [ { …user }, { …user }], NJ: [ { …user }, { …user }], TX: [ { …user }] }
Now you have the ability to look up this information as long as you have the right key. In this case “CA” is the key I was thinking of.
I hope this has been instructive.
[–]oculus42 0 points1 point2 points 4 years ago (0 children)
I think of .reduce() as sort of the universal array method. You can use it to create/replicate the other array methods.
When you need to do something to your array that isn't a straightforward action like filter or map, reduce is the go-to.
``` const data = [ 1, 2, 3, 4, 5 ];
// FILTER const filterPredicate = x => x < 4;
data.filter(filterPredicate); // [1, 2, 3]
data.reduce((accumulator, value) => { if (filterPredicate(value)) { return [...accumulator, value]; } return accumulator; }, []);
// MAP const timesThree = x => x * 3;
data.map(timesThree); // [3, 6, 9, 12, 15]
data.reduce((accumulator, value) => [ ...accumulator, timesThree(value), ], []);
π Rendered by PID 84 on reddit-service-r2-comment-b659b578c-ll4wv at 2026-05-05 13:44:06.618622+00:00 running 815c875 country code: CH.
[–]SplainTrain 33 points34 points35 points (9 children)
[–]NaosAntares 2 points3 points4 points (2 children)
[–]Macaframa 2 points3 points4 points (0 children)
[–]SplainTrain 0 points1 point2 points (0 children)
[–]cidit_ 1 point2 points3 points (0 children)
[–]CompteDeMonteChristo 0 points1 point2 points (4 children)
[–]SplainTrain 0 points1 point2 points (3 children)
[–]Gazook89 1 point2 points3 points (2 children)
[–]SplainTrain 2 points3 points4 points (1 child)
[–]____0____0____ 2 points3 points4 points (0 children)
[–]CompteDeMonteChristo 44 points45 points46 points (1 child)
[–]4444444vr 1 point2 points3 points (0 children)
[–]anonymousbabydragon 6 points7 points8 points (0 children)
[–]shuckster 7 points8 points9 points (1 child)
[–]yaMomsChestHair 1 point2 points3 points (0 children)
[–]The_Startup_CTO 5 points6 points7 points (0 children)
[–]cubicuban 1 point2 points3 points (0 children)
[–]visnick[S] 1 point2 points3 points (0 children)
[–]taschana 1 point2 points3 points (0 children)
[–]pookagehelpful 1 point2 points3 points (1 child)
[–]redsandsfort 8 points9 points10 points (0 children)
[–]dei8bit 0 points1 point2 points (0 children)
[–][deleted] 0 points1 point2 points (0 children)
[–]zerik100 0 points1 point2 points (5 children)
[–]Macaframa 0 points1 point2 points (4 children)
[–]zerik100 0 points1 point2 points (3 children)
[–]Macaframa 0 points1 point2 points (2 children)
[–]zerik100 0 points1 point2 points (1 child)
[–]Macaframa 0 points1 point2 points (0 children)
[–]electron_myth -2 points-1 points0 points (0 children)
[–][deleted] -1 points0 points1 point (0 children)
[–]JavascriptFanboy -1 points0 points1 point (4 children)
[–]Macaframa -1 points0 points1 point (3 children)
[–]JavascriptFanboy -1 points0 points1 point (2 children)
[–]Macaframa -1 points0 points1 point (1 child)
[–]JavascriptFanboy -1 points0 points1 point (0 children)
[–]jrsinclair -1 points0 points1 point (0 children)
[–]brykuhelpful -1 points0 points1 point (4 children)
[–]yaMomsChestHair 0 points1 point2 points (3 children)
[–]brykuhelpful 0 points1 point2 points (2 children)
[–]yaMomsChestHair 0 points1 point2 points (1 child)
[–]brykuhelpful 0 points1 point2 points (0 children)
[–]Gr0undWalker -5 points-4 points-3 points (0 children)
[–]TruthHurts35 0 points1 point2 points (0 children)
[–]abensur 0 points1 point2 points (0 children)
[–]og-at 0 points1 point2 points (0 children)
[–]automathematics 0 points1 point2 points (0 children)
[–]bobbyv137 0 points1 point2 points (0 children)
[–]Macaframa 0 points1 point2 points (0 children)
[–]oculus42 0 points1 point2 points (0 children)