sort() array method in order to make what I was writing make sense.
That function I'm going to share in a sequel. But I thought this got to come first - understanding
sort() is a native array method that takes an array, converts its elements into strings, and re-orders them according to their character's Unicode point value. Afterward,
sort() returns the "sorted" array.
sort()does not operate on a copy of the given array, the original array is mutated or lost. As you work with this method, you might learn of ways to run it on a copy of an array instead.
Consider two examples of
sort() in action:
var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'], numbers = [1, 300, 4, 67, 8, 9, 10] console.log(months.sort()) // [ "Apr", "Feb", "Jan", "Jun", "Mar", "May" ] console.log(numbers.sort()) // [ 1, 10, 300, 4, 67, 8, 9 ] console.log(months) // [ "Apr", "Feb", "Jan", "Jun", "Mar", "May" ] console.log(numbers) // [ 1, 10, 300, 4, 67, 8, 9 ] // Notice that the original arrays are gone - forever.
9 comes before
10 in the numeric system,
10's string's Unicode character precedes that of
Now, this default ordering might upset you. I mean, why, for example, should April come before January? You might need to define how you want your array to be sorted. Of course. It's why we got an optional, let's call it,
sorter() function to pass in as argument to
sort to override default.
There's but a few things to know about and do with
sorter(), which, as soon as you nail those, you should've understood
sort() and can work easily with the method. Let's see about those.
What you need to understand
Here's how you write the
var sorter = (a, b) => a < b ? -1 : 1
What you're saying there is that the function should compare each pair of elements and return either of
+1 depending on the size or order of the element. The question to ask is, why
1? Knowing the answer is what I needed to nail
If you're familiar with math, that's like a number-line comparison, where a negative number is less than a positive one and precedes the latter. Really, its a function like our
var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May'], numbers = [1, 300, 4, 67, 8, 9, 10] console.log(months.sort(sorter)) // [ "Apr", "Feb", "Jan", "Jun", "Mar", "May" ] console.log(numbers.sort(sorter)) // [ 1, 4, 8, 9, 10, 67, 300 ]
sorter() and do as dictated.
Now, with string data type, it kind of works, but alphabetically - April still coming before January. But knowing what is going on can help us get to whatever result we desire.
Incidentally, to have a random list of months sorted into the Jan - Dec order that we're used to, we'd have to define that order and instruct JS to sort according to ours. That? Yup, another post.
So, let's get to behind the scenes of
sort() - we've kind of left this off too long...
sortmutates the original array. It sorts the elements in the array, not a copy of it, and returns the sorted array, destroying the orignal. So, if you want to preserve the original array, sort a copy of it instead. Do something like:
// Spread the numbers array into a copy of itself before sorting [...numbers].sort(sorter)
- It is the
returnvalue of the
sorter()function, which is more or less called
compareFunction(), that determines how
b, that is,
element2, is compared. Why an element pair?
sortstarts its comparison in order to sort by picking the first element (index 0) of the array, which it assigns to
aand the second element (index 1), which it assigns to
b. Then it runs
sorter()on the pair. The next iteration,
aand the next element is picked as
b. And so on...
// Testing how sort picks elements var numbers = [1, 300, 4, 67, 8, 9, 10] numbers.sort((a, b) => console.log(a, b)) // You'll have a numbers.length - 1 number of loops/comparisons - 7 items in the array, so 6 loops /** 1 300 300 4 4 67 67 8 8 9 9 10 */
I mean, look at it, say you had
numbersarray. Then your last commparison loop, should be
10 250, right? Now, 10 is less than 250, so
10...ooo, lemme back up right there, because what I'm thinking is, since JS is sorting the array, re-arranging it, by the time it gets to 10, that is, whatever is at that index at that time, it may no longer be 10. So, my thinking of thinking a number higher might precede a lower one depending on the length of the array, should be flawed...or some...I shouldn't confuse you any further if you get the idea. 😊
- If the result of
sorteris less than 0 (kind of like -1), the instance of
ais sorted to an index lower than that of
b, meaning, it'll be placed before in the array.
- As in 5, if the result of
sorteris greater than 0 (kind of like 1), the instance of
ais sorted to an index higher than that of
b, meaning, it'll be placed after
bin the array.
- And, yet, if the result of
sorteris equal to 0, the positions of
undefinedelements are all pushed to the end of the sorted array.
When the array you're sorting is strictly numerical numbers, you can write
// A more succinct sorter for numbers var sorter = (a, b) => a - b
Is it making sense, though? Why do I feel I've babied the explanation a bit too much?
Let me close by saying
I don't want to leave off without sharing a line from the MDN doc that struck me. Which line, kind of backs the point I was trying hard to make in #4 of my list up there of the things you need to know of
... but sorted with respect to all different elements.
Look at that! The full quote is:
bunchanged with respect to each other, but sorted with respect to all different elements.
So, past "touched" items might not just be "left alone" like that, you know. They're kind of held up again against newer comparisons, just so that, in case, they either smaller or bigger in value, they might get switched around, if you get what I mean. I don't know if this is the best way to explain it, but I hope you get the idea. Or you can share how you might tell it in the comments. Cheers!