Sort can automatically arrange items in an array. In this lesson we look at the basics including how to sort an array of strings alphabetically and the correct way to perform a numerical sort on an array of numbers. We finish as always with a practical use-case that shows not only sort
in action, but also how it can be chained together with other array methods such as map
and join
.
[00:00] Array Sort sorts the elements in an array in place, and returns the same array. If we wanted to alphabetically sort this array of names, we could simply call items.sort, and then Log Items. You see we get the desired results.
[00:21] You can do the same with numbers. If we had 10, 30, and 20, that appears to have worked. However, this is not what you expect. When calling sort on an array with numbers, what actually happens is each number is converted to a string, and they're compared using their position in Unicode.
[00:45] We can demonstrate the problem this causes by placing a 2 here. Now we would expect that 2 is the first item, 10 is the second, and 20 is the third, 30 the fourth. But, when we run this code, we see a very strange result. We have 10 first, then 2, then 20 and 30. This is because, in Unicode, 10 does come before 2. Again, this is because these numbers are being converted to strings first.
[01:18] To pre-form a numeric sort on an array such as this, we need to provide a comparative function. A comparator has A and B being the left and right item of the sort algorithm. To sort this array in ascending order, we can simply provide A minus B and we get a correct sort.
[01:42] By providing a comparative function here, you're taking over how two values are compared with each. Whereas previously, these numbers were being converted into strings first, inside our comparative function, we just get the raw values, and that allows us to simply subtract B from A, and return the result of that subtraction to the comparative functions, which is then used to determine what action should be taken on the current item.
[02:12] The reason why something so simple as this works for a numeric sort, is that this comparative function only cares that you return either 0or a value less than 0or a value above 0For example, the longhand version of this might look something like, If A - B = 0return 0If A - B < 0return -1. If it's more than 0return 1. [inaudible] again, you see it still works.
[02:50] The interesting part here is that this number can be anything that's below zero, and this can be anything that's above zero, and that will still work. This explains why simply minusing B from A works. If we console log that, we can see it in action. You see we get some negative numbers and some positive numbers.
[03:12] When the underlying algorithm that's performing the sort calls this comparative function, it really only cares if the value is either zero, below zero, or above zero. That's why you can reduce all of this down to a simple expression A - B. To perform a descending sort, you would simply provide B - A, instead.
[03:38] We can make use of this comparative function in multiple ways. For example, if we go to having an array of names, this time we've added in Kitty, and we wanted to sort this array based on the length of the string. In this case, each value inside the comparator will be a string. Strings have a length property, so we can compare that instead.
[04:02] You see we have Kitty at the front, as we are using B - A, which gives us a descending order. Now let's look at a slightly more useful example. Let's use an array of objects, where each object represents a lesson as a title and a views count. We want to sort this array based on the amount of views, and then I'll put some HTML.
[04:28] We'll first create the list by sorting the lessons based on the amount of views. We want it to be in descending order, so that the most popular video is first. We'll call b.views - a.views. This will give us back an array on which we can call map. Then, we'll simply return a template string. We'll indent each line with four spaces, and we'll create an <li>.
[04:57] Inside of here, we'll say x.title, space, and then in brackets, we'll use x.views. Finally, we can join that together with a newline character, which will make up our list. Then we can create an output variable, which is another template string, which is a <ul>, has a new line, then our list, and then another new line.
[05:31] If we output this to the console, you can see we get the output we expect, which is a list of our items that have been sorted based on the amount of views. To recap, we take the lessons array. We provide a comparative function to the sort method, which sorts each lesson based on how many views it has. Sort gives us back the same array, although now modified.
[06:00] Then we call map, which is called for each item of the array. We apply a little bit of padding, just for the sake of output here. Then we access the title and the view. We join those together with a newline character, and then we wedge that in between a <ul>, with some more newline characters, which produces this output.
It is a pity that we are destroying our original list in this way. It would be nicer if "sort" as well as "map" created a new list.