Transcript from the "Exercise 26a" Lesson
>> Jafar: As you're writing your expressions, it's a really good coping mechanism, right, as you're finding you're building big expressions, to be able to print them out and see where you are. Now remember the key to solving problems using functional programming, using the style, is to continue mapping until you have an identifier bound to everything you need to create your final result.
[00:00:23] And then you can figure out how deeply nested your collection is and then figure out the right number of flattens to apply and where to apply them. So let's give a shot here on 26. Now it's been a while since I've seen this question. So I'm gonna be struggling through just like you guys, I know this is a hard one.
[00:00:38] So we're going with even deeper levels of nesting, so what I'm gonna do, by the way, from now on is I'm gonna try and just paste it into a text editor as these problems get bigger, right? It'll be a little easier for us to work in a text editor.
[00:00:47] So I'm gonna switch over to my text editor here. So here is the structure we have. So we have lists, we have videos. Now again, we're using a relational structure here. So every video has a listId, and then we have boxarts. And every boxart is within a video, so it has a videoId.
[00:01:08] And every bookmark is also in a video, so it has a videoId. So let's take a look at what we have to create. So we're going from a relational list to a hierarchical structure. So the video's array, so this is what we wanna produce.
>> Jafar: So let's take a close look at what's in here.
[00:01:34] So we've got our top level, we have an array of movie lists. Each movie list contains an array of videos, right? And each video contains id, title, time, and boxart. Now I'm guessing that time is gonna be,
>> Jafar: Pulled off of the bookmark, and I think it's the, is it the middle interesting bookmark or,
>> Jafar: Bookmark time and the smallest bookmark url.
>> Jafar: This says bookmark time, but I'm not sure which one cuz we've got several.
>> Jafar: Let's see.
>> Jafar: Has anybody finished that question can tell me it's the smallest bookmark time or the largest bookmark time? I expect it to be written here.
>> Speaker 2: I think.
>> Jafar: Which one was it?
>> Speaker 2: I think there's just one per videoId, right?
>> Jafar: I see, it's linked up for video by identifier. All right, is it linked up by identifier, or is it actually linked up by position? Let's see, bookmark, yeah, it's linked up by identifier.
[00:02:49] So we're gonna link up the bookmark to the video by videoId, the boxart to the video by videoId. And we're gonna link up each video to the list by id. So let's start at the very top because we wanna create lists. Lists are what's on the outside, right?
[00:03:03] So first, I'm gonna go through the list. I'm gonna create one object for each list.
>> Jafar: And I know I'm gonna be applying some concatAll here, so I'm gonna move my map to the next line because that's the rule. As soon as you have multiple verbs, you only want them on the next line lined up.
[00:03:27] So now I'm gonna go through each of the videos.
>> Jafar: So first things first though, actually I'm gonna create my list object because we know at the end of this, we want an array of list objects, right? So for every list, we wanna create an object containing properties, so I'm gonna create that right off the bat.
[00:03:48] And then that will contain a videos collection.
>> Jafar: Put that right in there, and there may be some other properties we want on there, I believe just the name of the list, so I'm just gonna stick that right in there, right now.
>> Jafar: So now we drill down because we know that next comes video, so now we start mapping over video.
[00:04:13] So there's an order here, it's the same order that we see in the hierarchy. So we start with lists, we move on to videos, and then within videos, we're gonna move on to bookmarks and middle interesting moment, or the time. So we go through the, I'm gonna move this down one line here, video.
[00:04:30] So first thing I'm gonna do is actually not map, but filter because I'm only interested in the videos where the video's listId is equal to the current list.id. And I move that on to the next line, notice as soon as I have, want more than one chained operation by move it on to the next line, and I indent.
[00:04:48] So for each one of these videos though, I'm gonna create a video object, and I wanna pull out which properties. I'm gonna pull out the id and title, so those are just some properties I'm pulling right off the video.
>> Jafar: And now comes the hard part. Well, I don't think it's any harder actually than the previous example, it's the same thing over and over and over again, right?
[00:05:19] Our structure, top to bottom, is just the same structure that we wanna see in the output cuz we know lists are at the top. So we map through lists first, videos are next. We map through videos first, and so on and so forth. Now the interesting thing though is recognize that when we go through boxarts and we go through bookmarks, right, there isn't a hierarchy here.
[00:05:36] They're both on the same level, they're both on the video level. So there's no reason to map over boxarts and then map over bookmarks any more than there is a reason to do them the opposite way, mapping over bookmarks and then mapping over boxarts. So effectively, we have access to both of these lists at the same time.
[00:05:50] So there's no particular reason to map because we don't have to go through one before we go through the other. So that may mean that we need to use a zip. I don't know actually, let's play around with it and try it out. Or we can just process them both at the same time.
[00:06:02] So let's see, I have title, and now we want time, and time is actually going to be the one bookmark time that matches up with this video id. So I'm gonna start doing something that I think is a mistake, and it's the same mistake we made all the way back in question 12.
[00:06:19] I think I've made a mistake here, which is, I've tried to create the result too early. We'll see if that's true. So I'm gonna go through bookmarks.
>> Jafar: And once again, I just need to match that bookmark id, video id up with the current video id. All right, and before I keep going here, do I have a problem?
[00:06:45] Can anybody tell me what my problem is?
>> Speaker 3: You have an isolated time on the bookmarks.
>> Jafar: Time, that's true, that's absolutely true. And I think I've used a map where I should be using a filter here, right? I should be filtering for where the bookmark ids are the same, not map, that's the wrong operation.
[00:07:09] So, you're absolutely right, let's map that in, right, so I've got a bookmark. And I just wanna pull up the time off that bookmark, that's one problem. And here, I wanna show off a way in which I think it's gonna be easier for folks to cope with these big structures.
[00:07:28] If we can sort of work more iteratively cuz notice this is big expression and we're kind of writing and writing, and we don't really know where we are, so here's a way that we can kind of cope with this. And it's also easier to do this in a text editor cuz you can see where you're inlining, where your brackets are matched up, right?
[00:07:44] So let me see, is that bracket matched up? No, I'm missing up here.
>> Jafar: So let's take a look at, sorry, question, yeah, or?
>> Speaker 3: Well, you need to map bookmarks with boxarts before you can.
>> Jafar: You're absolutely right, I do, but what I'm doing to demonstrate here is how we can just sort of work and print out what we have as we go, right?
[00:08:20] The key here is as long as we just do the map step first, as soon as we introduce concatAll, it's a little bit harder because concatAll only works on a two dimensional array, we have to make sure that each level we're using concatAll, we have to return a two dimensional array.
[00:08:34] So if we just don't do any concatting, we worry about this in two separate steps, just keep mapping until we have all of the identifiers we need in scope, notice that's what's going on here, right. That's how I'm bringing up and into scope all the things I need to do my job.
[00:08:50] If we just keep mapping, well, we're just gonna create trees, but the good thing about trees is we can print them out, then we can figure out how deep we are. So we don't have to be lost in a sea of just doing this all in our head.
[00:08:59] So I'm gonna try [COUGH] do this right here.
>> Jafar: So what I've done here with these last two parameters to JSON.stringify, actually I'm not entirely sure what the null is, I don't know offhand, but the 2 describes the indent. So now if we do it like this, JSON.stringify actually prints this out for us in a way that we can actually just see what's going on and see the indent.
[00:09:51] Just gonna return the result to make the function happy, we know we won't get the right answer. So we'll get an error here, but that's okay. We had that problem with the Firefox debugger earlier, but let's see if we can see if that still happens, turn off the toolbar.
[00:10:09] Any Firefox experts here who can tell me how to get that debugger to kick in?
>> Jafar: Here we go, I think.
>> Jafar: All right, so we're now at a point where we can actually log, instead of using the debugger, I'm just gonna log what we have. So, I've taken the expression so far, I've logged it out.
[00:10:38] Let's take a look at it. What am I doing wrong?
>> Jafar: We made this mistake in question 12. I made the same mistake that I think most people would make in question 12, which I started to create my object too early. I created my result too early, and then I found, no, I've still got this thing boxed up in an array.
[00:10:58] I wanna get this value out of an array. Can anybody see the value that's boxed up in the array that shouldn't be?
>> Speaker 4: Time.
>> Jafar: Time, right? I've hastily tried to create this object, but I haven't managed to get that value in the timer out of the array.
[00:11:11] So let's go back to our example. And well, I wanna map over time, right, clearly cuz that's the answer usually. In order to bind a variable, right, there's two ways to bind a variable to a collection, I can go item = arr
, or I can go arr.map, right?
[00:11:31] And this is the way we wanna do it. This is gonna work for synchronous and asynchronous collections. And both accomplish the same thing. But before I do that, I'm just gonna finish up. We're gonna get mostly there by just finishing up the example for, I believe, it's box arts.
[00:11:46] So I wanna link up the boxart with the video id, but I think this one is a little more challenging if I remember correctly, because you have multiple boxarts, and we wanna pick out which one, the smallest boxart, is it?
>> Speaker 2: There's just one.
>> Jafar: There's just one boxart?
>> Speaker 2: Yeah.
>> Jafar: Cuz I see here, no, I see here multiple.
>> Speaker 4: [CROSSTALK] In mine, yeah, it's the smallest.
>> Jafar: Yeah, so here's two boxarts with the same video id. So it looks like we do need to get the smallest. So I'm gonna stick, even though we know that isn't the right answer yet, we're gonna get a little bit closer.
[00:12:17] And what I'll do is actually, I'm gonna take the time section, and I'm gonna pull it out, and we're just gonna assign it to a variable.
>> Jafar: So we use filter and map because we knew we could just pull out the time, and the only condition to pick the right time was use the video id.
[00:12:37] So filter is the logical choice and then we notice that we just wanted to pull up the time property, and whenever you wanna just substitute an item in an array for some translation of that item, map is the right choice. But now we've got a little bit more of a challenge.
[00:12:50] We wanna get the boxart, and there's a little more to it. It's not just about filtering for video id, although that's definitely something we have to do.
>> Jafar: But now we have another challenge, which is how do I pick the smallest boxart, because this is actually gonna give me more than one result.
[00:13:16] It's gonna give me multiple results. So can anybody tell me the right operator use to use to pick the smallest boxart?
>> Speaker 2: Reduce.
>> Jafar: Reduce, why do I have to use reduce?
>> Speaker 2: Cuz you have to compare it.
>> Jafar: Right, in order to pick the smallest of something, I need to look at least two things at the same time.
[00:13:31] So if I use accumulated and current, right, remember how reduce works, we have a value that we've got in our hand that we're sort of holding on to, and that's the value that we're accumulating over time. And then we have the current, which is the value that's the current item in the array.
[00:13:46] So in order to pick the smallest one, I'm gonna return the accumulated boxart, width times height, we're gonna go with area. Oops, I don't need the return statement there. And I'm gonna move this to the next line, so it stays visible.
>> Jafar: And we want the smallest one.
[00:14:04] So if the accumulated width times height is smaller than the current width times current height,
>> Jafar: We're gonna return the accumulated, otherwise we're gonna return the current.
>> Jafar: Okay,
>> Jafar: So now, we have two arrays, each of which are one long, [LAUGH] which isn't super helpful, right?