Hello, I’m doing the functional programming challenges, but i don’t understand the reduce method. Can someone help?
The purpose of the reduce
method is to condense an entire array down to a single value. The function in the reduce
describes how each element contributes to the single reduced value.
Is there a specific part that is confusing you?
Can you give us a little more context? When you read a description of how the .reduce()
method works, what part gets confusing?
Is there are reason why there is map() and reduce()?
map
turns an array into a different array
reduce
turns an array into a single value
You pick one based on what you need to do.
I typically add the initial value for the reduce method. When you don’t provide an initial value, JavaScript assumes you want to start with the first object in the array.
Technically, .reduce
can do everything that .map
can do (and more), but it’s much more verbose. To double each value of an array with .map
:
const doubled = arr.map(e => e*2)
The same with .reduce
:
const doubledWithReduce = arr.reduce((acc,e) => {
acc.push(e*2);
return acc;
},[])
.reduce
also avoids the kind annoying sitation when you want to loop over an array and compare each value to the one before. For an array of length 5, those are 4 comparison operations, so you always have to wrap the function body in an if (i > 0)
statement. For example, finding the biggest value in an array (let’s forget we have Math.max()
for that) is very simple with .reduce
:
const biggest = arr.reduce((acc,e,i) => acc = e > acc ? e : acc);
This only works because .reduce
assigns the accumulator to the first item in the array and skips that first step, if no initial value is provided.
I mean… you can bully map
and reduce
to accomplish the same things, but using a reduce
to make an array or using a map
to condense an array to a single value is a huge anti-pattern.
I wouldn’t use .map
to reduce ( ) an array down to a single value, but I admit I’d definitely use
.reduce
when I want to do something to each value of the array and also change its length. I’ve never heard that .reduce
always should result in a single primitive value. For example, I think a good use case where you return an array from .reduce
is when you want to flatten the array and have better browser support than with .flat
, but as usual - personal preference.
Yeah, I’d totally use reduce
to change an array’s size in situations where a filter
is not appropriate. Flattening an array is one of the example uses of reduce
on MDN.
Though, I think you can use a flatMap
(which I just discovered) in some of those sorts of situations.
I suspect that reduce
is often used in a way that doesn’t result in a single primitive value. I’ve used it more often to compose something like an object from an array of objects. I can’t, off the top of my head, think of a case where I would use reduce
to turn an array into a shorter array…that feels more like something I would use chained filter
and map
methods for. It seems pretty hacky - which isn’t to say that it wouldn’t work or be an effective/efficient solution in some cases.
Agreed that a chain .filter().map()
is often a good choice (like, take an array of values, first filter out those that aren’t numbers, then map over the remaining ones to double the values).
Whenever I find myself chaining .filter
only because I had to return undefined
for some items in my .map
code, I think .reduce
is the cleaner solution (like, map over an array of values, double them if they’re numbers and otherwise return undefined
, then filter out undefined
). But I should add that I’m more thinking of algorithm challenges than real world examples here.
I would use a filterMap
to do that sort of thing in a different language, and I think flatMap
can do the same thing in JS. The annoying thing with chaining is that you do two passes over your array, which is slower than a single pass.
Thanks so much for pointing that out a second time, I always thought .flatMap
had to do with JS Map objects (something I’ve ignored so far) and couldn’t be bothered to look it up.
It looks like a Map
is a hashmap? All of my high order method knowledge I learned in Rust, so I have to keep trying to ‘map’ all the JS lingo back to what I know.