In this lesson, we will be looking at two common mistakes programmers make when working with reduce.
We will see why we always need to pass in an initial value for our accumulator as well as return the accumulator.
[00:01] You know how JavaScript has a bunch of these curiously endearing little features? Like if you say console.log number one equals string one, what's it going to say? It's going to say true, because it's trying to help you. You have to go out of your way to make sure you use the triple equals in order to get JavaScript to acknowledge that these are not actually the same thing.
[00:24] Well, there's something similar when you're reducing arrays. Let's say we have an array of numbers. Textbook reduce example here, and we want to add these numbers up. We know the way this works. We know we're going to have a function called a reducer. It's going to take our accumulator. It's going to take our value. It's going to return the accumulator plus the value.
[00:45] We know that if we say var sum equals data.reduce with this reducer, then that's going to add those up. But I made a mistake here. Do you see what it is? I need to give it the initial value for the accumulator, and I didn't. You might expect this to fail.
[01:06] But actually it's going to work just fine. Wait a second. How did that happen? I thought the accumulator is always what got passed in as the returned value from the previous time the reducer was called. So the very first time it runs, when the value is one, this accumulator should be undefined.
[01:24] Well, in the JavaScript implementation of reduce, they've got this handy little feature where if you don't pass in an initial value, it just assumes that the first item in your array is your initial value. This works like exactly for one scenario, which is when you're trying to add up a list of numbers.
[01:42] If you're trying to, I don't know, tally up votes or something, like how many votes were cast for each of these values, and you want to do something like this, where if accumulator has a value for that key, accumulator value equals accumulator value plus one. Otherwise accumulator value equals one. Then you just return the accumulator.
[02:21] The way you normally do something like this is you pass in that empty object. When we run this, we can see we had two votes for each of these things. What happens if we leave this out in this case? Weird.
[02:41] The accumulator was just vote one. Because when we didn't specify an initial value, it assumed that this is our initial value. Strings are primitives. They can't have properties, and so this always resolves to false. What's going to happen is that that initial value is just going to get returned every time.
[03:03] Bugs like this can happen. They're incredibly hard to understand or figure out what the hell's happening. It's not like it's throwing an exception. It's not like it's returning undefined. It's returning a value. It's just, where the hell did that come from?
[03:18] Another common mistake that you'll see is if you forget to return the accumulator. You do your logic, but you don't actually...Let's not be making two mistakes at once here. You've got all your logic, everything is good, but you forgot to return the accumulator, and now it's saying the accumulator value is undefined? What do you mean the accumulator is undefined? I set this in here.
[03:42] Well, this is actually the second time it runs, because the first time it ran it never returned a new accumulator. Accumulator became null the second time this ran, and you're going to get that kind of an error.
[03:54] Two takeaways here. Number one, always pass in an initial value for your accumulator. Never rely on the fact that it'll automatically work when you're summing numbers, because the bugs you're going to find are really quite magnificent. Number two, always double check and make sure that you're actually returning the accumulator.