Functional JavaScript First Steps, v2

Implement Reduce Function Exercise

Anjana Vakil
Software Engineer & Educator
Functional JavaScript First Steps, v2

Lesson Description

The "Implement Reduce Function Exercise" Lesson is part of the full, Functional JavaScript First Steps, v2 course featured in this preview video. Here's what you'd learn in this lesson:

Anjana explains the functional implementation of the reduce function. Students are then instructed to implement reducer functions for sum and max operations.

Preview
Close

Transcript from the "Implement Reduce Function Exercise" Lesson

[00:00:00]
>> Anjana Vakil: Okay, when we come to reduce,
>> Anjana Vakil: It might be kind of mean of me to make you implement this cuz it's hard enough to use a reduce function. So what we're gonna do is just read through this implementation of the reduce function, but then we're going to implement, instead of reduce itself, we're gonna implement some reducer functions.

[00:00:21]
Cuz this is kinda the tricky part, if you ask me, about working with reduce. And the pattern is really not that different from what we've seen so far. We have our base case. If there's nothing in the array, then we just return the value, the first value, the only value.

[00:00:40]
And that value is gonna be set by a variable called the initialValue, which you sometimes might see written as accumulator or something like that, or sometimes abbreviated to acc. So you might see that a bit, but I'm just gonna call it initialValue. And this is gonna be whatever I want to come back from this reduce operation if, let's say I give it a sliced piece of bread and I'm asking it to reduce me a sandwich, then I should expect that same sliced piece of bread out.

[00:01:17]
But for other things like maybe sum, I might start out with a different initialValue, wink, wink. Okay, so what we're gonna do, we're gonna take in in reduce the reducer function and the array, but also that initialValue, and that's gonna be kind of our toe hold that we use to do the rest of the reduction, okay?

[00:01:36]
All right, so then, if we have zero, we're done with our base case. Otherwise we're gonna compute a new value by applying the reducer function to this accumulated value, accumulator value, excuse me, which is initialValue here. Or again, you could imagine renaming all of these to accumulator or acc.

[00:01:58]
But we're going to apply the reducer function to the initialValue and the first thing in the array, and that's gonna give us back one value. And we're gonna save that. In this case, I've just saved it to a variable to make it more clear what we're doing, and we're gonna pass that in as the initialValue for our recursive call to reduce.

[00:02:20]
So it's like we're updating the accumulator. We are accumulating values, which is why we call it an accumulator sometimes, and we're gonna call reduce again recursively. But this time we're gonna pass in the newInitialValue or the new accumulator, and the tail of the array. And recursively, we're gonna do the whole thing over and over again until we hit an empty array, and then we pop back out with just one value that represents the entire smushing, if that makes sense.

[00:02:54]
The whole sandwich in our example. So the trick to using reducers then becomes the reducer functions that we pass to them. So let's take a moment to fill out the sum and max functions. Both of these are going to use our function reduce, which is already implemented for you.

[00:03:17]
And they're gonna take in an initial value, which you have to figure out what it should be. It's not undefined, probably. [LAUGH] And it's gonna take in our array, and it's going to make one value out of this array that is what we expect. So in sum, it should be, if we give it an array of numbers, it should add all of those numbers together and give me the sum of all of those numbers.

[00:03:40]
And for max, if we give it an array, I want it to return the largest value in that array, right? So if I give it an array of numbers, I want it to return the highest number. So we're just gonna assume we're only working with integers and numbers here, cool?

[00:03:57]
Okay, you got this.
>> Anjana Vakil: Let's start with sum.
>> Anjana Vakil: Okay, so we said a reducer function has a certain shape, which I've just reminded you of in this little blue call-out here.
>> Anjana Vakil: It takes the accumulator value, or the initialValue here, and then the,
>> Anjana Vakil: Array value we want to be accumulating into that accumulator, if that makes sense.

[00:04:39]
So essentially, we're gonna have function signatures that look like here, just a way that you often see it is accumulator value goes to some kind of something, some kind of value. Well, yeah, now let's think about if we're given an array where we've just got, let's say, a whole bunch of the rest of the sum already, and we have a new value that's come up in our array.

[00:05:06]
To keep accumulating the sum, I'm gonna use?
>> Speaker 2: Addition.
>> Anjana Vakil: Addition, so I'm going to return my fat arrow, accumulator plus value. Oop, I called it v, let's see now, yeah? Now we need to fix the initial value and start off with the sum of an empty array would be?

[00:05:34]
>> Speaker 3: Zero.
>> Anjana Vakil: Snake eyes or something, okay? [LAUGH] No, that's once, never mind, okay? [LAUGH] So sum, it seems to be passing. Max is failing, cool. All right, questions? So this is why we're often working with reducers like, what is the reducer I need? And that's what we're practicing here.

[00:06:01]
All right, let's do one more, max. So same function signature, we're gonna have an accumulator and the value, or the initialValue and a new value to accumulate. And this time, instead of adding them together, I want to return cuz I wanna get the highest [LAUGH] value from the accumulator or the value?

[00:06:32]
>> Anjana Vakil: Can anyone help me make that happen?
>> Speaker 4: We probably want a ternary declaring accumulator and value.
>> Anjana Vakil: We're gonna need some comparing. Okay, let's think through. So we're gonna ask ourselves, is the value bigger than my previously biggest value which is gonna be stored in the accumulator?

[00:06:59]
And if so?
>> Speaker 5: Return the value.
>> Anjana Vakil: Then the accumulator is going to become, or the new accumulator value is gonna become value cuz it's bigger. And if not? [INAUDIBLE]
>> Anjana Vakil: Yes, and small gotcha, because of JavaScript, yeah?
>> Speaker 6: It's starting with undefined, so you want to put a number there to be the max.

[00:07:30]
So if there is no accumulator, you need to set it to the value.
>> Anjana Vakil: Okay, right, so if we have undefined in here, and probably, if I'm asking you for the max, and I don't have a lot of comparisons to make, that's legit. So we wanna make sure to handle that case of, what if the value is undefined or the accumulator is undefined?

[00:07:55]
So in that case, it's gonna start getting a little harder to read here, but you'll often see sometimes ternary split over multiple lines like this, right? So we're just gonna keep doing this, and we're going to kind of nest another little ternary in here, and we're going to test if we're returning the accumulator.

[00:08:19]
Let's double check that it's not undefined, yeah? So if it's undefined,
>> Anjana Vakil: Then we will return-
>> Speaker 7: Value?
>> Anjana Vakil: Value, cuz actually, even though JavaScript thinks that [LAUGH] it's not the case that, I don't know, a five is, well, maybe if we wrote it the other way, it would be.

[00:08:44]
But anyway, it's undefined, it messes with us. We're just gonna handle this specifically. And if not, then we'll return the accumulator. Feel reasonable?
>> Speaker 7: We could just set it up in the base case on top too where it's if not acc or value is greater than acc,
>> Anjana Vakil: Right, so we could also, sorry, if-

[00:09:07]
>> Speaker 7: Yeah, rather than-
>> Anjana Vakil: Right, we could test the equals equals could go up here. There's a few different ways we could nest this, all good. But in principle, does this seem reasonable? So yeah, so sometimes these little reducers, even though they're very tiny functions, can be a little bit of like a?

[00:09:26]
So this is the fun that we get to have. But the thing is that it's really nice to be able to not care about how many things you have in your array when you're trying to compute a single value out of that array, and the accumulator is how we do that.

[00:09:42]
Because it's a function, it's pure functional programming, so we don't have state. We can't just remember max value seen so far between different calls to the function. We don't wanna do that kind of stateful programming. So instead, we turn what we need to remember into data that we then manipulate as needed to keep remembering what we need to.

[00:10:10]
So this is kind of a principle we're gonna come back to later in the course is that if we're used to using state as a way of remembering values and remembering data and where we're at in an operation. For example, what the value of i is in my for loop is a way of remembering how far I am through all of the loops I need to go.

[00:10:32]
In functional programming, what we will be ending up doing is taking whatever we need to remember and making it an input of the function, making it a value itself. Not something that's part of the program that could maybe be different than I thought it was, but just a single value.

[00:10:49]
So if I know I'm getting that value in, I know what result to expect instead of needing to look at the program state to figure it out.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Start a 7-Day Free Trial