0 1 00:00:00,210 --> 00:00:09,240 In the last lesson we started using the map function to loop through our data and map pieces of data 1 2 00:00:09,300 --> 00:00:11,790 to our reusable components. 2 3 00:00:11,790 --> 00:00:18,060 Now in this lesson I want to go through map in greater detail and also look at some of the related functions 3 4 00:00:18,120 --> 00:00:24,990 that help us deal with arrays such as map, filter, reduce find, and find index. 4 5 00:00:24,990 --> 00:00:30,540 So go ahead and get the starting code sandbox and then go ahead and fork your own copy. 5 6 00:00:32,520 --> 00:00:40,880 All right so here I've got an array of numbers up at the top and what map allows us to do is to loop 6 7 00:00:40,910 --> 00:00:49,580 through the array and create a new array by doing something with each item. 7 8 00:00:49,580 --> 00:00:56,420 So as you saw the way that we call this is we need to get hold of an array in order to call map on it. 8 9 00:00:57,050 --> 00:01:03,650 And inside this map function it's going to expect a function. 9 10 00:01:03,650 --> 00:01:06,660 So we're passing a function into another function. 10 11 00:01:06,710 --> 00:01:13,760 Now the function that we pass in will determine what we actually want to do with each item. 11 12 00:01:13,760 --> 00:01:20,420 So let's say that I wanted to maybe double each of these items. So I could create a function that takes 12 13 00:01:20,420 --> 00:01:27,530 an input x and simply just returns the value of x multiplied by 2. 13 14 00:01:27,530 --> 00:01:30,740 So this is a doubling function and it's pretty simple. 14 15 00:01:30,950 --> 00:01:37,460 If I pass this function double into my map function, then it's going to loop through my numbers array 15 16 00:01:37,730 --> 00:01:45,410 and for each of the numbers in there it's going to put it as the input of this function and output a 16 17 00:01:45,410 --> 00:01:51,390 new array with each item replaced with double the size of the previous one. 17 18 00:01:51,410 --> 00:02:00,240 Let's go ahead and try it out. This method has an output and that output can be either captured, so let's 18 19 00:02:00,270 --> 00:02:10,090 call it new numbers and we can go ahead and console log it so you can see in our console that we're 19 20 00:02:10,090 --> 00:02:18,640 getting the values 6, 112, 4, 96 and 10, each of which are double the size of each of the items in our 20 21 00:02:18,640 --> 00:02:26,610 numbers array. Now if you think about this, this is not exactly something that we couldn't do before right? 21 22 00:02:26,970 --> 00:02:34,940 Because we already knew about the forEach and we've been using it to loop through arrays for a long 22 23 00:02:34,940 --> 00:02:36,470 time now in the course. 23 24 00:02:36,480 --> 00:02:41,960 So if we wanted to do this with forEach we could have done it like this. 24 25 00:02:42,120 --> 00:02:49,650 We could have created a new variable called newNumbers and set it to an empty array and then we could 25 26 00:02:49,650 --> 00:02:54,460 have gotten hold of our numbers array and then called forEach. 26 27 00:02:54,720 --> 00:02:59,090 And then inside this forEach function it also expects a function 27 28 00:02:59,100 --> 00:02:59,750 right? 28 29 00:02:59,790 --> 00:03:08,700 So let's go ahead and create another double function which takes a number x and it gets hold of this 29 30 00:03:09,000 --> 00:03:17,880 newNumbers array and pushes a new value which is going to be x multiplied by two into that newNumbers 30 31 00:03:17,970 --> 00:03:25,670 array. And then we can pass that function double into this forEach loop. 31 32 00:03:25,690 --> 00:03:29,620 So this is how we would do it using the forEach 32 33 00:03:29,620 --> 00:03:34,970 rather than using map. So you can see that map is a lot more concise. 33 34 00:03:34,990 --> 00:03:40,390 Now you might be thinking, "Well actually, when we've been using for each we don't actually define a separate 34 35 00:03:40,390 --> 00:03:41,560 function right?" 35 36 00:03:41,620 --> 00:03:49,480 So we could in fact make this a lot simpler by putting that function inside the forEach and making 36 37 00:03:49,480 --> 00:03:52,450 it anonymous by removing its name. 37 38 00:03:52,450 --> 00:03:55,970 So it would look something like this, a little bit simpler 38 39 00:03:55,990 --> 00:03:56,590 right? 39 40 00:03:56,710 --> 00:04:00,850 But equally we could have done the same with our map function. 40 41 00:04:00,850 --> 00:04:10,090 We can also make that a lot simpler if we wanted to by simply putting this function inside the parentheses 41 42 00:04:10,540 --> 00:04:16,030 and then removing its name and turning it anonymous. Which ever way you do it 42 43 00:04:16,030 --> 00:04:24,400 you'll notice that it's more concise using map because this function itself actually returns an output 43 44 00:04:24,820 --> 00:04:26,890 which is a new array. 44 45 00:04:27,250 --> 00:04:33,790 So unlike forEach where we have to create a new empty array and then every time we do something with 45 46 00:04:33,850 --> 00:04:40,980 each item inside the array we push to the new array. Instead with map 46 47 00:04:40,990 --> 00:04:43,060 it just does it all by itself. 47 48 00:04:43,060 --> 00:04:51,870 This is really really handy in React when we're creating custom components and mapping data to it. Now 48 49 00:04:51,890 --> 00:04:56,760 another related and also quite a useful function is filter. 49 50 00:04:56,940 --> 00:05:00,360 Let's say that we've still got our numbers array up here, 50 51 00:05:00,360 --> 00:05:02,630 so let's just move it a bit closer. 51 52 00:05:02,910 --> 00:05:05,250 And I wanted to filter on it. 52 53 00:05:05,370 --> 00:05:12,870 Well as the name suggests, what it does is it's going to create a new array by keeping only the items 53 54 00:05:13,020 --> 00:05:14,990 that return true. 54 55 00:05:15,000 --> 00:05:16,050 What does that mean? 55 56 00:05:16,050 --> 00:05:17,680 Well let me show you a demo. 56 57 00:05:18,060 --> 00:05:25,380 Let's say that we have our numbers array and I call the filter method and inside here again it expects 57 58 00:05:25,440 --> 00:05:26,260 a function. 58 59 00:05:26,760 --> 00:05:30,200 Let me write it out. Instead of creating a separate function 59 60 00:05:30,210 --> 00:05:33,900 I'm just going to create an anonymous function inside here. 60 61 00:05:33,960 --> 00:05:41,280 This filter function is going to look through each of the numbers inside this numbers array and for 61 62 00:05:41,280 --> 00:05:48,940 each of these numbers, it's going to return only the ones that meet a particular criteria. 62 63 00:05:49,140 --> 00:05:55,020 So we could say something like return num > 10. 63 64 00:05:55,140 --> 00:06:01,370 In this case, we're looking through this numbers array here and we're checking each of the numbers. 64 65 00:06:01,380 --> 00:06:03,940 So we first start with 3 then 56. 65 66 00:06:04,080 --> 00:06:08,510 And for each of these numbers, we're checking to see if they're greater than 10. 66 67 00:06:08,790 --> 00:06:15,100 And if they are then we're going to add it to a new array which is going to be the output of this function. 67 68 00:06:15,120 --> 00:06:20,470 So let's create a const called newNumbers and set it to equal this. 68 69 00:06:20,550 --> 00:06:27,050 And then we can go ahead and console log it. And you can see we get 56 and 48 69 70 00:06:27,090 --> 00:06:33,800 the only two numbers that are greater than 10. Now you can of course switch this up so make it create 70 71 00:06:33,800 --> 00:06:39,330 an array where the numbers must be less than 10, in which case we get 3, 2, 5. 71 72 00:06:39,530 --> 00:06:46,910 And this is basically a way of adding a filter to your array and providing a condition that you want 72 73 00:06:46,910 --> 00:06:47,920 to check for. 73 74 00:06:48,020 --> 00:06:55,760 And if that condition is met and then create a new array with those items that actually return true. 74 75 00:06:56,240 --> 00:07:03,050 I find it quite helpful usually thinking about these methods map/filter/reduce in the context of a method 75 76 00:07:03,050 --> 00:07:07,320 that you should already be pretty familiar with which is the forEach. 76 77 00:07:07,340 --> 00:07:13,910 So let's think about how we might do this with a forEach loop. So we might create a new numbers array 77 78 00:07:13,910 --> 00:07:15,710 which is going to be empty, 78 79 00:07:15,710 --> 00:07:22,520 then let's get hold of our numbers and then call forEach on it and then inside here will add an anonymous 79 80 00:07:22,520 --> 00:07:27,920 function which will loop through each of the numbers inside here. 80 81 00:07:27,920 --> 00:07:32,840 So we have access to each of the numbers inside our numbers array and then we're going to check, we're 81 82 00:07:32,840 --> 00:07:35,630 gonna say if num is, 82 83 00:07:35,630 --> 00:07:39,310 so we were checking less than 10 up here, less than 10. 83 84 00:07:39,320 --> 00:07:48,500 Well then in that case we're going to push this number which meets this criteria into our array of new 84 85 00:07:48,500 --> 00:07:49,060 numbers. 85 86 00:07:49,280 --> 00:07:55,640 So newNumbers.push and we're going to push num in there. 86 87 00:07:55,670 --> 00:08:01,940 Now when we log new numbers, you can see it's still the same but it obviously took a lot more effort 87 88 00:08:02,030 --> 00:08:06,050 than simply just using the filter function. 88 89 00:08:06,050 --> 00:08:14,690 Now the final one that sort of fits inside this set map/filter/reduce is the reduce function. 89 90 00:08:14,690 --> 00:08:22,160 So the reduce function works by accumulating a value and doing something to each of the item in an 90 91 00:08:22,160 --> 00:08:22,840 array. 91 92 00:08:22,910 --> 00:08:28,480 So sounds a little bit confusing as well but it will be less confusing when we actually see it in action. 92 93 00:08:28,940 --> 00:08:34,760 Let's say that I wanted to add and sum up all of the items in my numbers array. 93 94 00:08:35,330 --> 00:08:42,260 Well if I wanted to do that with forEach then I would have to say something like numbers.forEach. 94 95 00:08:42,320 --> 00:08:47,360 And then let's create an anonymous function in here for each number in numbers. 95 96 00:08:47,510 --> 00:08:55,200 We're going to create a new variable which will call newNumber and set it to 0. 96 97 00:08:55,610 --> 00:09:03,860 And then inside this loop, we would have to get hold of a newNumber and add the value of the current 97 98 00:09:04,430 --> 00:09:06,900 number in the array. 98 99 00:09:06,980 --> 00:09:15,970 So it might help if I actually rename this currentNumber. What this loop does is it goes through all 99 100 00:09:15,970 --> 00:09:22,150 of the numbers in this array and for each of the current number that it's looping through, 100 101 00:09:22,150 --> 00:09:27,420 so the first time it'd 3, then it's going to add that number to our new number. 101 102 00:09:27,460 --> 00:09:31,360 So 0 becomes 3 and then the next time it loops around 102 103 00:09:31,420 --> 00:09:39,430 this is 3 and it becomes 59 etc. etc. until we end up with the final value so we can go ahead 103 104 00:09:39,520 --> 00:09:45,220 and log newNumber which is equal to 114. 104 105 00:09:45,250 --> 00:09:48,090 This is the roundabout way of doing it. 105 106 00:09:48,100 --> 00:09:52,030 Now what if we wanted to do it using our reduce function? 106 107 00:09:52,030 --> 00:09:53,670 Well it's actually a lot simpler. 107 108 00:09:53,710 --> 00:10:05,050 So we could say numbers.reduce and then we can pass in a function which takes an accumulator as 108 109 00:10:05,050 --> 00:10:08,590 well as the current number. 109 110 00:10:08,590 --> 00:10:13,800 And this is going to be the equivalent of that previous variable. 110 111 00:10:13,990 --> 00:10:20,470 And then this is going to be the number which is equal to each and every iteration through the array. 111 112 00:10:21,580 --> 00:10:24,160 And then inside the reduce function 112 113 00:10:24,160 --> 00:10:33,400 I'm going to return the accumulator plus the current number and if we go ahead and save this to a variable 113 114 00:10:33,400 --> 00:10:38,800 called newNumber, because we're really console logging it down here, then you can see the result is the 114 115 00:10:38,800 --> 00:10:42,750 same as the previous method using forEach. 115 116 00:10:42,820 --> 00:10:46,900 Now it might help if you actually go ahead and just console log 116 117 00:10:46,900 --> 00:10:52,900 the value of accumulator and current number every time the loop is run in order to understand how this 117 118 00:10:52,900 --> 00:10:59,140 reduce function works. You can see that the first time the loop is run the accumulator is already set 118 119 00:10:59,200 --> 00:11:04,100 as the first value and the current number gets set as the second value. 119 120 00:11:04,210 --> 00:11:08,910 The next time it's run, the accumulator has already been added to the current number. 120 121 00:11:08,950 --> 00:11:14,890 So it's now equal to 56 but the current number now moves onto the next item in the array and so on and 121 122 00:11:14,890 --> 00:11:22,680 so forth until we get to the end of the array and we end up with our total value. 122 123 00:11:23,010 --> 00:11:29,100 So those three functions are probably some of the most useful JavaScript functions that actually exist 123 124 00:11:29,190 --> 00:11:36,300 even before ES6. If you take a look at the MDN and develop a docs for map, filter and reduce which 124 125 00:11:36,330 --> 00:11:42,780 are linked to in the course resources, you can take a look at how they work and what parameters they 125 126 00:11:42,780 --> 00:11:48,530 take but also notice how their compatibility is across all browsers. 126 127 00:11:48,540 --> 00:11:56,160 This was introduced way before ES6 and you can safely use this code anywhere on any browser. But the 127 128 00:11:56,160 --> 00:12:02,160 next two that I want to talk about, the find and find index, were actually introduced relatively recently. 128 129 00:12:02,880 --> 00:12:04,410 So what are they useful for? 129 130 00:12:04,800 --> 00:12:11,330 Well find is a function that's going to help you find the first item that matches in an array. 130 131 00:12:11,760 --> 00:12:22,020 So for example inside our numbers array, we could go ahead and call numbers.find and again it expects 131 132 00:12:22,080 --> 00:12:23,240 a function. 132 133 00:12:23,340 --> 00:12:32,190 So let's loop through all the numbers in our numbers array and then go ahead and find the first value 133 134 00:12:32,310 --> 00:12:34,780 that is greater than 10. 134 135 00:12:34,890 --> 00:12:44,230 So return num greater than 10. What this does, unlike the filter, is it's not going to loop through the 135 136 00:12:44,230 --> 00:12:45,020 entire array. 136 137 00:12:45,070 --> 00:12:52,600 It's going to stop as soon as one of these returns true. If we go ahead and save this to a constant 137 138 00:12:55,300 --> 00:12:56,230 and log it, 138 139 00:12:56,260 --> 00:13:01,780 you can see that it loops through our array but it's stopped as soon as it found the first item that 139 140 00:13:01,780 --> 00:13:07,230 was greater than 10. And find index works in a similar way. 140 141 00:13:07,260 --> 00:13:15,340 But instead of finding the first item instead what it does is it finds the index of the first item that 141 142 00:13:15,340 --> 00:13:16,270 matches. 142 143 00:13:16,270 --> 00:13:21,870 So in this case if we change find to find index, you can see it works pretty much the same way 143 144 00:13:21,940 --> 00:13:28,630 but now we're getting the index of that first number that matches the criteria which is of course the 144 145 00:13:28,630 --> 00:13:32,490 index 1 because arrays start from 0. 145 146 00:13:32,750 --> 00:13:36,850 So all of these functions are not for you to memorize. 146 147 00:13:36,890 --> 00:13:44,180 It will be really hard to remember all of these. But instead I recommend really understanding what's 147 148 00:13:44,180 --> 00:13:48,580 going on and what the goals are of each of these methods 148 149 00:13:48,590 --> 00:13:49,940 map, filter, reduce, 149 150 00:13:49,940 --> 00:13:56,210 find and find index so that when you actually have a need for something that one of these functions 150 151 00:13:56,210 --> 00:14:01,520 might be able to help you achieve somewhere in the back of your mind you might have a light bulb go 151 152 00:14:01,520 --> 00:14:07,100 off and think oh yeah there was a function somewhere whether it was ma, filter or reduce I can't remember 152 153 00:14:07,370 --> 00:14:13,760 but one of these can probably do what it is that I need. and then go and have a look at the docs and 153 154 00:14:13,760 --> 00:14:19,940 find the function that you actually need and then quickly look through the demo and the documentation 154 155 00:14:20,240 --> 00:14:24,280 to see what it actually does and how to use it. 155 156 00:14:24,290 --> 00:14:31,670 So as I always stress, memorization is not what we do in the post at Google world. 156 157 00:14:31,670 --> 00:14:36,710 So in order to test your understanding, I've got a challenge for you. 157 158 00:14:36,710 --> 00:14:39,930 Go ahead and comment out any code that you've already got. 158 159 00:14:40,310 --> 00:14:46,700 And feel free to save it inside this code sandbox for future reference if you want. But you'll notice 159 160 00:14:46,700 --> 00:14:53,180 I've also included the emojipedia file that came from our previous code challenge. And what I want 160 161 00:14:53,180 --> 00:15:01,790 you to do is to go ahead and import the emojipedia constant from our ./emojipedia file. And 161 162 00:15:01,790 --> 00:15:08,560 then you'll remember that the emojipedia constant is also an array right? 162 163 00:15:08,600 --> 00:15:16,610 So when we log it you can see we've got an array of three objects and each of these have a property 163 164 00:15:16,640 --> 00:15:20,120 called meaning which contains a whole bunch of text. 164 165 00:15:20,150 --> 00:15:28,370 So your goal is to create a new array that just has the meaning text. 165 166 00:15:28,370 --> 00:15:31,640 For example this one, this one and this one. 166 167 00:15:31,700 --> 00:15:41,430 But here's the catch. You have to truncate the text so that it only has a maximum of 100 characters. Here's 167 168 00:15:41,430 --> 00:15:45,060 what it would look like if you have completed the challenge successfully. 168 169 00:15:45,120 --> 00:15:50,430 So here's my new array that I've created using some sort of function. 169 170 00:15:50,490 --> 00:15:58,500 And it logs each of these emoji meanings but it caps them, if you notice, at a hundred characters. 170 171 00:15:58,590 --> 00:16:00,870 So they are all equally long. 171 172 00:16:00,960 --> 00:16:02,100 And this is kind of useful 172 173 00:16:02,100 --> 00:16:09,720 a lot of times when we're creating websites where we want these sizes of cards or boxes to be even across 173 174 00:16:09,780 --> 00:16:17,340 our entire page. And we might just do a truncation like what I've got here. As a hint, you will need to 174 175 00:16:17,340 --> 00:16:23,400 use a another method which you might have come across ages ago in the Javascript section which is called 175 176 00:16:23,400 --> 00:16:27,690 substring. I've linked to the documentation on this method 176 177 00:16:27,690 --> 00:16:28,590 so have a look at it. 177 178 00:16:28,590 --> 00:16:34,990 Have a think about this problem and see if you can achieve this outcome and complete the challenge. Pause 178 179 00:16:35,010 --> 00:16:36,300 the video now and give it a go. 179 180 00:16:39,750 --> 00:16:40,120 All right. 180 181 00:16:40,140 --> 00:16:49,380 Our starting point is three objects in an array. So we know that the map function helps us create a new 181 182 00:16:49,380 --> 00:16:53,870 array by doing something with each of the items. 182 183 00:16:53,910 --> 00:16:56,660 And that kind of matches what we want right? 183 184 00:16:56,760 --> 00:17:01,220 Because in our case we want to create a new array of meanings. 184 185 00:17:01,440 --> 00:17:08,400 And the doing something is to truncate it to 100 characters and we're going to do that to each item 185 186 00:17:08,610 --> 00:17:11,490 in this emojipedia array. 186 187 00:17:11,490 --> 00:17:15,170 Now that we've settled on the map function, let's go ahead and call it. 187 188 00:17:15,200 --> 00:17:18,570 So we'll say emojipedia.map. 188 189 00:17:18,570 --> 00:17:25,860 Now inside this map function, it of course expects a function which is going to give us every single 189 190 00:17:26,130 --> 00:17:27,550 emoji entry. 190 191 00:17:27,600 --> 00:17:29,940 So let's just call it emojiEntry. 191 192 00:17:29,940 --> 00:17:34,050 So we've got three emoji entries each are an object. 192 193 00:17:34,320 --> 00:17:39,150 And the first time this loops through it, what do we want to do with the emoji entry? 193 194 00:17:39,150 --> 00:17:40,650 What do we want to do with it? 194 195 00:17:40,650 --> 00:17:48,090 Well we want to take the emoji entry, so let's just focus on the first object for now, the emotive entry's 195 196 00:17:48,150 --> 00:17:49,090 meaning, 196 197 00:17:49,140 --> 00:17:57,480 so we're going to be tapping into emojiEntry.meaning, and we're going to try and use substring to 197 198 00:17:57,510 --> 00:18:01,560 cut it down to 100 characters. Based on this demo 198 199 00:18:01,560 --> 00:18:09,990 you can see that these substring takes the string and cuts it between the index specified at the first 199 200 00:18:10,050 --> 00:18:11,790 and the second positions. 200 201 00:18:11,790 --> 00:18:14,430 So in this case 0 1. 201 202 00:18:14,460 --> 00:18:18,630 So it starts from 0 and ends at 3. 2, 3. 202 203 00:18:18,630 --> 00:18:26,610 So we end up with 'oz' printed out. In our case if we want 100 characters printed, we can simply 203 204 00:18:26,670 --> 00:18:33,000 use these substring method and cut it from 0 to 100. 204 205 00:18:33,150 --> 00:18:38,760 Now that we've got this newly formatted meaning, what are we going to do with it? 205 206 00:18:38,760 --> 00:18:41,040 Well we're just going to return it. 206 207 00:18:41,040 --> 00:18:48,660 And what this does is it's going to build a new array which we can save into a constant newEmoji 207 208 00:18:48,800 --> 00:18:58,530 pedia and it's going to create it from the meanings in our emoji entries from our emojipedia with only 208 209 00:18:58,530 --> 00:19:00,480 the first hundred characters. 209 210 00:19:00,480 --> 00:19:09,480 So let's go ahead and log this new emojipedia. And you can see that I've now got this new array and I've 210 211 00:19:09,480 --> 00:19:12,590 cut the meanings all at a hundred characters. 211 212 00:19:13,020 --> 00:19:15,290 So they are now equally long. 212 213 00:19:15,480 --> 00:19:23,760 And this is achieved by using our map function which maps through this emojipedia array 213 214 00:19:24,060 --> 00:19:31,500 and for each of the entries I've gotten hold of the meaning text and then I've cut it down to the first 214 215 00:19:31,500 --> 00:19:39,450 hundred characters and then I've returned it to be added to this new array. If you didn't manage to complete 215 216 00:19:39,450 --> 00:19:45,990 this challenge I recommend heading back to your code and trying to do this yourself from scratch and 216 217 00:19:45,990 --> 00:19:48,810 play around with the code until it makes sense. 217 218 00:19:48,840 --> 00:19:55,260 It's also worth having a quick read of each of these pieces of documentation which as usual is really 218 219 00:19:55,260 --> 00:20:01,700 high quality and really helps you get even more understanding of each of these functions. 219 220 00:20:01,740 --> 00:20:08,760 Now in the next lesson, we're going to learn about something that is ES6 specific and it's going 220 221 00:20:08,760 --> 00:20:13,160 to help us to cut down on the length of our functions even more. 221 222 00:20:13,470 --> 00:20:20,170 And that is the fat arrow also known as the Javascript arrow function. For all of that and more, 222 223 00:20:20,250 --> 00:20:20,840 I'll see you there.