JavaScript Sorting Arrays

JavaScript has a sort() method that you can use on arrays, but the results are almost always weird and don’t return what you initially expect.

For example, if you have the following [9, 8, 12, 1, 33, 21] array, using sort() on it will return [1, 12, 21, 33, 8, 9].

On the surface, this makes no sense, and that’s because JavaScript’s sort() method isn’t exactly what it makes itself out to be. The array returned is hardly sorted at all — or maybe it is, but just not in the way we want it to be.

This is because JavaScript’s sort() method converts each item in the array into strings and constructs the sequence by comparing each array item based on the UTF-16 code values when there is no callback specified.





UTF what?

I know. Welcome to the seemingly weird but highly logical parts of JavaScript.

How UTF-16 Works

JavaScript is not a typed language — as much as many of us want it to be. When sort()is used, it automatically calls the String() cast method on every array element by default and turns everything into a string. It does this in order to ensure that things can be sorted in a uniform manner. It’s easier to sort when things are the same type.

UTF-16 stands for 16-bit Unicode Transformation Format. It’s the standardized form for translating bits into a format comprehensible to humans. It’s basically a translation table for a corresponding character.

When you use JavaScript’s sort(), you are essentially sorting against whatever order the characters are in for this table. That is why 33 came before 8 in the sorted array above. It is because the character 3 appears before 8 in the table. The sort is done based on character appearance rather than mathematical reasoning or rules.

When this logic is applied, JavaScript’s sort() method isn’t wrong — it’s merely misunderstood.


How to Turn Numbers Into Numbers ?

When sort() is used on its own, it returns values based on the order of things in the UTF-16 table. However, sort() also takes a callback function that allows you to decide how things will appear.

On a technicality, it’s more a comparison function that helps your JavaScript code determine the correct order of things in the manner you want.

This callback function takes two arguments — a and b — for convention purposes. You use these arguments to create an equation that either returns 1, -1, or 0.

When the equation returns 1, a gets to proceed. If the equation returns -1, then b gets to proceed. If the equation equates to 0, then it means that both are equal in value and it is the end of the recursive sorting algorithm sort() runs through.

So when you’re working with numbers and using the callback function, the String() cast is not placed on the array items. This is because sort() needs a callback comparator, and when sort() is used without one, String() acts as the default callback.

What About (a, b) => a- b ?

In many tutorials and StackOverflow answers, you may have seen solutions that look something like this: arrayNameHere.sort((a, b) => a - b);.

The thing with 1 and -1 is that it doesn’t have to be these two numbers specifically. It just needs to fall into one of the two spectrums of either being a positive or negative number. sort() will still treat it the same way as the code example above.

0 is a definite number that signifies the end of the sorting recursion, so this is the only non-negotiable value.

This is why (a, b) => a - b works. For example, if a = 5 and b = 2, a - b results in a positive number, making a the bigger number and returning the equivalent of 1.

It is good to note that this kind of sort logic only works with numeric types or objects that return numeric values when valueOf() is used.

Comments

Popular posts from this blog

Accenture Jobs 2022 Insurance Domain

Infosys, Capgemini, Google, S&P are recruiting nerds, Check subtleties

Tesla lays off 200 Autopilot workers in most recent positions cut: Report