This course has been updated! We now recommend you take the Functional-Light JavaScript, v3 course.

Check out a free preview of the full Functional-Light JavaScript, v2 course:
The "Challenge 7: Solution 3" Lesson is part of the full, Functional-Light JavaScript, v2 course featured in this preview video. Here's what you'd learn in this lesson:

The last step in the exercise 4 solution is to incorporate the filter() method so only odd or even values can be passed to addn().

Get Unlimited Access Now

Transcript from the "Challenge 7: Solution 3" Lesson

[00:00:00]
>> Kyle: Okay, so that's been the iterative and then recursive approach. And I'm going to use that same inspiration of that algorithm for my third and final approach to this which is, I'm going to implement that with a list operation. So if I have function addn and I bring in a list of functions.

[00:00:23] [INAUDIBLE] further up. Bring in a list of functions. [COUGH] Essentially what I'm doing is I am taking two functions and putting them together. And then taking two functions and putting them together, and taking two functions. Is that sound like a list operation that we've talked about so far?

[00:00:42] All right, so let's try to write this function using the reduceList operation, cuz we're taking two items, putting them together. Two more items, putting them together. That's fundamentally a reduce. So, [COUGH] I will call the fns.reduce,
>> Kyle: And let's stop for a moment before I even write it and think, what is the end result of my reduce gonna be?

[00:01:11] If I take two functions and make them into another and take two and make them into another. At the end of that reduce, what do I have?
>> Kyle: I have one giant function, right? I haven't actually computed it yet, so to do the actual computation, I need to not forget to put that last execution in there, of that function.

[00:01:34] Now my reducer is gonna take, and we typically call the reducer, we typically call those parameters acc and v, at least to start out with. [COUGH] I'm going to rename those in a moment but if we think about it, my reducer is taking a running function that's getting bigger, and bigger, and bigger, and combining it with this other function.

[00:01:58] So acc can really be though as is composedFn, And then v would just be the fn. And the new combined value is a single function that calls addn. So I need to make a function that calls add2 with composedFn and fn.
>> Kyle: So that is-clean up some of my spacing here.

[00:02:40] That should be the final implementation for addn. There's no base condition to concern ourselves with. There's no for loop or anything, we're just gonna let the reduce operation model that iteration. So this is, has more a kind of the iterative approach than in does with the recursive approach.

[00:02:58] This is not resurging but it is a nice simple and declarative way of saying, what we want to have happen. Which is we want this list of functions to all compose themselves. So I will take that and double check that I didn't mess it up.
>> Kyle: And there we got the 35.

[00:03:21]
>> Kyle: [COUGH].
>> Kyle: Somebody's asking in chat about the recursive one, so I just wanna go back to the recursive one for a moment. The base condition is that fns.length is equal to 0. So I'm only running this recursive command if the item is less than 0, I mean greater than 0.

[00:03:48] So I could've re-written that as; if fns.length is equal to 0 and done this command, that's our base condition. And then left the return statement by itself, if we're not in the base condition. So maybe that's a cleaner way of expressing that, but looks a little bit more like the recursion you're used to writing.

[00:04:20]
>> Kyle: Okay, so to item 6 in our readme, start with an array of odd and even numbers with some duplicates. So I'm gonna take out this one for now.
>> Kyle: And I'm just gonna make a list of some random numbers that I'll make up. So let's say 1, 3, 4, 2, 0, 9, 8, 3, 2, 1, 6, 4, 9, 3, 2, 3, 8, 10.

[00:04:57] Just made up some numbers. Have no idea what the end result of those numbers is gonna be. But then it says to trim those down to have only their unique values. So essentially we need to make a unique function. So there's two different ways that we could go about doing the unique.

[00:05:16] You might have started thinking, well that seems like a filter operation. If I have a list of repeated numbers and I need to trim it down to not have any of those repeats. I might just wanna filter that last. The problem with the filter is that you only receive the single value, and if you're only receiving a single value, you can't answer the question of, have I seen this value before?

[00:05:41] It's designed to make the decision entirely based only on that value. So filter by itself is not a particularly good approach. Although I'm gonna leave it here and come back because there is a trick that we can use for filter. Instead, what we really need to do is think about this in more general terms.

[00:05:59] We're gonna need to compare the value to something else which is the running list. And that should throw up an alarm bell in your head that we wanna use the reduce utility to do that. Because the reduce utility can be started with an initial value that's an empty list.

[00:06:18] And then we can build that list up a little at a time. So if I make a reduce call here, my reducer is gonna have a running newList and a value. And I need to provide an initial value here. This one I definitely need initial value. I'll start it out as and empty array.

[00:06:40] Now in the case that v is not already in the new list then I wanna add it. So I'm gonna say if newList.indexOf(v) = -1, meaning I did not find it, then we wanna add it to the newList.
>> Kyle: And then of course we need to always keep returning that reference to newList.

[00:07:09] So we are only going to put it in if it passes that check, if you will. Now there is something to point out here which is we are mutating the new list array that was passed into us. That should set off a little alarm bell in your head.

[00:07:30] Wait a minute, we aren't supposed to do that kind of thing. We don't really actually control that list. That is being passed into us. And because we don't we probably should be more careful and not assume that it's okay to mutate. So a nice simple way of doing that is to just simply concatenate the value instead of pushing it.

[00:07:55] Concat will create a whole new list with that value added on to the end. If we run this, just to test and make sure that it I didn't make a mistake there. We get down to that list of values. Now the next item in our readme, item 7 says, filter that array to only have even numbers in it.

[00:08:26] Speaking of filter, I mentioned there was trick where we could've done this uniqueness with filter. Let me show you how we could have done it with filter. In JavaScript specifically the built in filter, you get more arguments past a filter than just the value. Each one of these utilities will also pass standard the index at which that item has been found and the array that you're operating on.

[00:08:53] Those are arguments that JavaScript's filter automatically passes in. Armed with those additional pieces of information, I could say, if the index that I found this value at is equal to the return value of calling indexOf, cuz index always works from left to right. Then I know that this is the first time I've seen that value in the list and it's okay for me to put it in.

[00:09:20] But if it's not equal, then it must be one of the duplicate references in the list and so I shouldn't put it in. So the trick is to say if idx = arr.indexOf(v) then I wanna put it into the list. So that's return true, otherwise return false. Either of those two approaches would have been fine to do you making, I think the reduced one is a little bit clear.

[00:09:55] This is using a trick. So I'm gonna leave that one off. But we do wanna filter our newly uniqued list. We do wanna filter it down to, it says to include only the even numbers in it, so let's call a filter. And we'll give it a predicate function, and that predicate function needs to return true if it's even.

[00:10:18] And that's the same as if calling mod 2 on it returns 0. So let's double check that our list of numbers is now down to the even numbers.
>> Kyle: All right, now the read me says in item 8, and we wanna take the list of values and produce a list of functions.

[00:10:52] So the hint there is that we're gonna wanna call the map utility. And normally, I would say we're just gonna receive the value and then we wanna make a function that will return that value. But we already have a utility that does that. That's the constant utility.
>> Kyle: And then when I look at that, I say well, that looks like a point to me that could be point 3.

[00:11:20] So why don't I just use constant as my mapper function.
>> Kyle: So now we're gonna have produced a list of numbers that then became a list of functions. Given that final result list of functions, we should now be able to pass that array into add in. And if my quick mental math is correct, I believe we should end up with the value 52.

[00:11:51] So crossing my fingers with live coding again, there we go.
>> Kyle: Bring back up the final solution.
>> Kyle: What questions can I answer about exercise seven?
>> Speaker 2: [COUGH] Do you see any value in composing those function together, rather than chaining them to reduce the filter and map?
>> Kyle: Which function are you talking about composing?

[00:12:26]
>> Speaker 2: The reduce, filter, and map. So isn't taking an input of numbers and then we're passing them through a series of functions, right?
>> Kyle: Yep.
>> Speaker 2: Do you see a value in composing those, rather than chaining them like that?
>> Kyle: There is definitely a benefit to doing so.

[00:12:43] It's interesting that you bring this up, because that's a good segway to what our next unit, our next units of discussion are gonna be. But since you bring it up, I'll just ask look at the shape of each of those functions. Look at the shape of constant, it takes in a value and returns a value.

[00:13:01] And compare that to the shape of the predicate function which takes in a value and returns a true/false. And then compare that to the shape of the reducer, which takes in two values and returns a single value. There's three functions have different shapes, if you were to try to compose three functions together that have different shapes, is not gonna work.

[00:13:25] So it would be nice if there is a way to compose these together but giving that we currently know right now in the course. About composition, we only know how to compose functions that have the same shape. So now putting a little mental bookmark there we're later gonna talk about how to compose functions that have different shapes.

[00:13:46] So that's where we're heading.