<v Presenter>We come now to the third</v> of our three functional functions, reduce. Reduce is similar to map and filter in many ways, but it is the most complicated of the three. So in this section, we'll look at two examples. One focusing on the sum of an array of numbers and a second that converts an array like this, an array of strings, as our states array, into a JavaScript plain object consisting of key value pairs where the key is the string and the value is the length of the string. We'll start with the simpler example. Let's go down to the end of our file and define an array of numbers. (keys clacking) And this will just be one up to 10. (keys clacking) And our task is to sum the numbers in this array. As before, we'll first solve it an imperative way. (keys clacking) Our imperative sum function will take in elements, as with the other imperative solutions. And indeed there are a lot of parallels. So, we'll start with a variable called total. (keys clacking) It starts at zero, instead of an empty array, we start with in effect an empty number, a number that starts at zero. And then for each number in the array of elements, we'll increment this total. (keys clacking) Let's just call it N instead of element to indicate that it's a number, (keys clacking) of course, JavaScript doesn't enforce that. If you give it a list of things other than numbers, then it'll do something weird. But here we can just do total, instead of pushing, we will plus equals. So we accumulate the result in this total and then return it. (keys clacking) Take a look at this. Ah, there we are, 55. And that is indeed the sum of one up to 10. There's a trick by the way, the sum of one up to 10 is 10 times 10 plus one, divided by two. So 10 times 11 is 110, divided by two is 55, so we can check it. And it's right. So now let's talk about reduce, because this is especially tricky, I wanna do it in the REPL. Let's grab the numbers here. (keys clacking) Okay. So this is how reduce works, (keys clacking) numbers dot reduce. Now, instead of taking only one argument like this here, you can see with map or filter, we have element, elements, just one, reduce takes two parameters. The first parameter is the thing that we're accumulating in. So that, in this case here, is total. So, we have to have a second set of parentheses because there are two parameters. Remember, we could eliminate the parentheses in the case where there's only one parameter, but when there are two, we have to do it like this. Total, and then each element. In this case we'll call it N. So, numbers dot reduce, total, comma, N, fat arrow. This is tricky, so it takes some getting used to, and then we give it our function. And in this case, what we're going to do is increment it, total plus equals N, and then we wanna return the total. (keys clacking) Close curly brace. So, this is the first argument. It's an anonymous function. We're gonna give reduce a second argument, though, which is the initial value. In this case, zero. So let's take a look at this. Total equals zero, elements dot, for each, function N. So for each number, total plus equals N, and then return total. So we're essentially putting that into here. What reduce does is goes through every element in the array, does whatever this stuff is in here, in this case, we're accumulating in total, and then returns it. And it does this over the entire array. So you might think, well, this is exactly the same thing, but it's not. We're returning total in every case. Each call to return, returns total to the next element in the array. It's a subtle distinction but as with map and filter, reduce lets us march through the array and do something with each element, returning the result all at once. The result of this operation is, in effect, to reduce the contents of the array down to a single number. In this case, the sum of the elements in the array, that's why this method is called reduce. Although, as we'll see in our second example of reduce, the name, doesn't always make intuitive sense. See if it works, should be 55. Well, it worked, but we can make a couple of refinements. The first relies on a property of this plus equals operator in JavaScript. So suppose we said, let I equal zero, (keys clacking) and suppose we said let J equals I plus equals one. (keys clacking) So it's kind of weird, we're assigning, I plus equals one to J. So what this will do is increment I, and then return that value and put it into J, like this. (keys clacking) So that means that in this reduce up here, instead of doing total, plus equals N, return total, we can just do return total, plus equals N like that and put it in a single line. We can do comma zero. Again, the initial value. Should be 55 again, there it is. By the way, if we put, say a hundred here, I can show you that this is the initial value. That's 155, but there's one more refinement, which is that the default initial value is zero. So, we can do this. That means in here, we can replace this. Let's just copy and paste. (keys clacking) Functional solution, functional sum. Oops, lowercase. Replace all these, and then instead of this accumulation, we can actually just do this. (keys clacking) And return it. (keys clacking) 55, 55. Now, I find reduce to be by far the hardest of these three. Map and filter are fairly intuitive but reduce takes a lot of getting used to. So it's okay if this looks completely confusing. And in fact, even moreso than with map and filter, I frequently write the imperative version first before converting to a reduced version. As is so often the case though, repetition is a great way to learn. So let's take a look at the second example I mentioned, which is to form a JavaScript plain object consisting of key value pairs with the keys or the strings in this array and the values are the lengths of the strings. We'll start as usual, with our imperative solution, say lengths. (keys clacking) And so what we want is a JavaScript basic object called lengths, which we'll initialize as the empty object. So just a plain object. And then we'll go through the elements and we'll assign the key element to the length of the element. So let's just do that. Elements for each, element, (keys clacking) or we can use the bracket notation, square bracket, element equals element dot length (keys clacking) and then return lengths. (keys clacking) By the way, you may recall that there are two ways to access the attributes of these plain objects. We can do square bracket notation or the dot notation, but you can see here there's no way to do this with the dot notation. We can't do dot element because then that's literally just the element property of lengths. In this case, each element is really a string, so we need to use the square bracket notation. If we did this, JavaScript would have no idea what we're talking about. In fact, let's run it. Oh, we actually haven't called it. (laughs) Put it here. Imperative lengths of states. (keys clacking) Yeah, so you can see it actually sets the key corresponding to the string quote element, which is not at all what we want. What we want is this, lengths of, in this case, Kansas, Nebraska, North Dakota, South Dakota, check this out. There we go. So, Kansas has length six, Nebraska, eight, North Dakota, you can see here JavaScript switches to quotes because there's a space in here, it's length 12. South Dakota length 12. So this is the kind of thing that might be useful if you wanted to go through a long document. And, for example, calculate the histogram of word lengths. All right, let's do it the functional way. Let's go back here to the file. I'm gonna copy it 'cause it's really quite similar in many ways. And in fact, it's actually not gonna be a one-liner the way it was before, except it will be one statement. It could technically be one line. So, let me show you what I mean by that. (keys clacking) So this is functional lengths. All right, well, we've got this here, this reduce. See if we can figure it out and we'll do this here, let's call it. Okay, so it's going to be elements dot reduce. We'll try to do the same thing we did here. Reduce, well, the variable will be the accumulator. Instead of total, it's going to be lengths. And instead of N, we have element, same as the argument of this function here, (keys clacking) fat arrow, open curly brace. So here we're going to use the lengths parameter to accumulate the result, moving from one element in the array to the next, because of this pattern, in some contexts, and in some languages, reduce is called accumulate. This stands in contrast to our previous use in the sum where we were in effect, reducing the array down to a single number using total. And so here, we did return, total, plus equals N. But remember, before we had in the REPL, this here, total, plus equals N, return total. So we're gonna have to go back to this way of doing things. So we're gonna say lengths of element. That's just this here. We can just copy this. You can see we're taking what we did before. In fact, let me cut it just to emphasize that that's what we're doing. We're gonna cut this here, and then we'll return lengths inside of reduce, like that. (keys clacking) And there's one more thing. Remember, in the REPL we saw here, there's an initial value. The default is zero. In fact, we can run this, see what happens. So we have to return this statement like that. I'm gonna run this. I'm actually not sure what's gonna happen here. Yeah, look at that. So it just returns Kansas. I'm not really sure what happened there, but it started with an initial value of zero and it got confused. So what we have to do is give it an initial value of, well, the same thing we had before, let me command Z this back. You can see here, let links equal the empty plain object. So that's what we need here, like that. And I like to line things up inside here, just to make the block structure clear and see if this works. Yes, look at that. They're identical. So, this is a lot of work. It's not obviously better, the way the other ones were where it was just a one-liner but you can see that this is one logical statement, return elements dot reduce, lengths, starting at the empty plain object, comma element, lengths of each element is the length of that element, and then return lengths. But where is this returning it to? It's returning it to the next element in the array. So, I find this very confusing. This is incredibly difficult, but you can see that it is in fact just one logical statement. We can, in principle, do this. (laughs) It's not very nice to look at, but this is just one statement. It still works. Return elements dot reduce, and then this stuff. So even though we format it like this for convenience, in fact, logically, it's really just one JavaScript statement. Now, I really like reduce. And in fact, I feel like the ability to use reduce is really a hallmark of a programmer who's leveled up, but it is really tricky. So, let me tell you a little bit about my favorite technique which I mentioned briefly before and which we'll look at in detail in the next chapter. It's a technique that combines functional programming with a method called test driven development. So what you do, is you write an automated test which we'll see how to do in the next chapter that will pass only if your code runs properly. So in this case, we would write a test that would look for this return value. That test would initially fail because we wouldn't have working application code. We would just have test code. And then what you do is you write the imperative solution which generally is easier to understand than the reduced solution and is sometimes easier in the case of map and filter as well. And then finally what you do, is you refactor the code. That involves changing the form of the code without changing the function. In this case, we would refactor something like imperative lengths into a functional lengths function, except instead of having a whole separate function with a different name, we would actually change the function we were interested in. And with an automated test, any mistakes we make in converting from the imperative to the functional solution would be caught right away. So that brings us to the end of our introduction to functional programming. It's definitely not wrong to write programs the imperative way, but I think you'll find that as you become more and more experienced, you'll develop a deeper and deeper appreciation for the power and elegance of functional programming, especially when combined with automated tests, which we'll find out more about in chapter eight. But first we need to take some time to learn a little bit more about JavaScript's object system, which is the subject of the next chapter.