Deep JavaScript Foundations, v3

Function Expression Solution: Functions

Kyle Simpson

Kyle Simpson

You Don't Know JS
Deep JavaScript Foundations, v3

Check out a free preview of the full Deep JavaScript Foundations, v3 course

The "Function Expression Solution: Functions" Lesson is part of the full, Deep JavaScript Foundations, v3 course featured in this preview video. Here's what you'd learn in this lesson:

Kyle live codes the first part of the solution using function declarations.

Preview
Close

Transcript from the "Function Expression Solution: Functions" Lesson

[00:00:00]
>> Kyle Simpson: We're back to talk about the function expressions exercise. Hopefully you've found this one is efficiently challenging, twist your brain around thinking about functions and their names and where functions belong and how to define them. And especially with the arrow functions, the differences and there can be very stark differences in readability between those styles.

[00:00:22]
We're gonna start by implementing the printRecords function. Again the spec here, if you will, is asking us to take in a list of student Ids, get the student record by it's student Id. And I've already noticed, you could notice that there's going to be at least one other place where we need to to do that, and that's gonna be down here.

[00:00:43]
So I already know that's a utility I'm gonna need, accessing a student record by its ID. So I'm gonna start by writing that function first, I'll say function getStudentById, and that's gonna take in the studentId.
>> Kyle Simpson: And it needs to return me the record from that array. So it's got a search through the array and find the one that matches by the ID.

[00:01:09]
We don't need to implement our own search algorithm because JavaScript arrays as vs six heavy find method on them. So we're just gonna simply use, and the array that we're looking over is called studentRecords, so we're gonna say studentRecords.find(). And the find() function takes a callback, that callback is invoked for each item in an array.

[00:01:32]
And whenever the first of those returns true or a truthy value, then that value from the array is returned, not the true, but the array. It's almost like filter, we basically just need to return true whenever we have found the thing that we want. So, if we have matched the studentId, for example,

[00:01:57]
>> Kyle Simpson: I'll just use record here. The way we know that we have matched an ID is if the (record.id == studentId).
>> Kyle Simpson: And that will find the record in the array and return it, I'm gonna need that very first off in my printRecords. So, the very first thing that I wanna do is turn my list of record Ids into a list of studentRecords, all right.

[00:02:25]
Because this may not be the whole list of recordIds, so I'm basically getting a subset, by ID of the records that I wanna print out. So I can do a map function for that, I can take the recordIds,
>> Kyle Simpson: Which is an array of numbers studentIds, and I can map it and turn it into an array of student records that I can then print out.

[00:02:50]
So, but first I'll have to sort them, so that function I'll call getRecord, okay. So I'm taking in a studentId, and I need to go find it and then I immediately realize already have this macro function, right? That's the one that I just wrote, so basically getStudentById is my macro function.

[00:03:15]
Are you with me? Instead of passing that in as an inline function expression I have it as a standalone function, because I have the foreknowledge of knowing I'm gonna need that a second time here in just a moment. [LAUGH] Okay, so what we get back we could call records.

[00:03:33]
These are the student records that we wanna print, but we can't print them just yet because we need to sort this list by name. So we need to say records.sort, the sort function is,
>> Kyle Simpson: Frustratingly a mutator rather than returning a new array, it mutates in place for performance reasons.

[00:03:54]
So we don't actually need to say records equals records, that sort, we can just call records.sort and it mutates it. You could get a return value if you cared, but I tend to think the return value makes it look like it's not mutating in place when it is so, I usually just call it as a mutator, all right.

[00:04:11]
So, sort if you call it with nothing it does an alpha numeric sort on the values, and the problem with that is our values are objects and they are gonna string of by two objects as we talked about the types unit. So, we're gonna need to provide a function call back that can do the comparison.

[00:04:30]
So I will call this function call back, sortbyNameAscending, according to what it said. And the way this function call back works is it receives two records. So we will receive record1, and record2, and what we're supposed to do is if record1 is less than record2. Meaning record1 should show up earlier in the list, then were supposed to return something less than 0 like -1.

[00:04:57]
If it's greater than record2 we're supposed to return 1, and if it's equal to we're supposed to return 0. So, we can say if (record1.name < record2.name). Now we have the advantage of knowing that in this data structure the names are always strings. So this last thing is not gonna course it's just gonna do in alpha numeric comparison.

[00:05:23]
If the string is less than this one, alpha numerically then it's gonna sort early in the list. So if record1.name is less than record2.name, then we can return -1. If record1.name > record2.name, we an return 1, and otherwise, we'll return 0.
>> Kyle Simpson: Yes?
>> Speaker 2: Just as a practice question.

[00:05:55]
Even if assuming you knew that sortByNameAsc by name ascending you would not be using anywhere else. Would you ever consider extracting that?
>> Kyle Simpson: Yes I would.
>> Speaker 2: And then just have records.sort, sort by, okay.
>> Kyle Simpson: And it's especially true because this sort by name ascending function doesn't rely upon anything in the lexical scope, it doesn't need to be embedded.

[00:06:17]
Well, we will actually come to that question in another exercise. So we have sorted the list of records, now we simply need to print the records. And again because the spirit of the exercise is to use functions, let's use our friend, forEach. We can say records.forEach.
>> Kyle Simpson: And we're just gonna do a simple console.log statement here, I'll say record.name.

[00:06:50]
And then in parenthesis I'll say record.id and then we'll have an expression here that if they are paid we'll say paid. So record.id I'm sorry record.paid which is true or false, and we'll say paid or not paid.
>> Kyle Simpson: Okay, so there is our print record function. Now paid students to enroll, the expect the read me requirement say that it should look throughout the student records.

[00:07:29]
Checking to see which ones are paid but not yet enrolled, meaning they have a paid of true but their ID is not already in that current enrollment array. So, let's see that what we're going to get is a list of idstoEnroll, and then what we're going to return is a new array that includes the current enrollment.

[00:07:55]
So we will spread out the currentEnrollment, and then we will include whatever we've got in idsToEnroll.
>> Kyle Simpson: So how do we get the idsToEnroll? Well, we can start with the studentRecords.
>> Kyle Simpson: And we can filter studentRecords,
>> Kyle Simpson: That was only going to get us down to the studentRecords, and then we're gonna need to map that list into a list of IDs.

[00:08:29]
But we can start by filtering the studentRecords, and so we will say, needsToEnroll.
>> Kyle Simpson: And we wanna keep it in that list if record.paid, meaning they have paid and they are not already in current enrollment. And there is a built in JavaScript array method called includes also added this time in ES 2016.

[00:09:07]
Array includes searches for a value in the array and gives us true or false if it's there. So we don't need me to do that down little index of trick that we used to do. So I can simply say if current enrollments if not current enrollments includ.record, that gives me a record, but I don't need a record.

[00:09:27]
What I actually need is the ID, so now I need to do a map which gets the StudentId from the record.
>> Kyle Simpson: And now that populates idsToEnroll. So we have not modified the currentenrollment, we're simply returning the new array for you to do something with it. Finally we have the remindUnpaid, again the requirements say that we should take a list of studentIds.

[00:10:01]
Filter that list to only those whose records are in unpaid status, and then pass that filtered list to printRecords. So we're gonna do another filter, this time we're gonna do recordIds.filter, and what we're gonna get back from that is the unpaidIds.
>> Kyle Simpson: Now we have the student id but we need the record.

[00:10:43]
So we need to get the record by saying record = and then we use that little helper that I wrote earlier, getStudentById.
>> Kyle Simpson: And then we need to say, if record.paid if not record.paid.
>> Kyle Simpson: So that will give me the list of ids who's record is in the unpaid status, then I should simply pass that list into printRecords.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now