Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding Javascript .sort parameter

I am having trouble understanding why the following function sorts the string numerically (in the third section of the code) .

var myArray = [10, 44, 32, 100, 0, 44, 3, 4];
console.log(myArray.toString()); // 10, 44, 32, 100, 0, 44, 3, 4 --> unsorted

myArray.sort();
console.log(myArray.toString()); // 0,10,100,3,32,4,44,44 --> sorted like strings

// this is what confuses me:
myArray.sort(function (a, b) {
return a - b;
});
console.log(myArray.toString()); // 0,3,4,10,32,44,44,100 --> sorted numerically

Specifically:

  1. How do a and b get populated?

  2. Why is does subtracting a - b sort the numbers in numerical order?

  3. How do all the numbers get sorted into proper order if the function is only examining 2 numbers at a time? (i.e. a and b)

like image 992
jon Avatar asked Feb 17 '13 23:02

jon


2 Answers

.sort takes an optional parameter, which should be a function.

.sort then calls that function repeatedly, passing it a pair of values from the array (the a and b parameters). The function then returns a value which is interpreted like so:

  • If the returned value is less than 0, then a < b
  • If the returned value is greater than 0, then a > b
  • If the returned value is exactly 0, then a == b

Using this, .sort figures out the order of the items using whatever sorting algorithm the browser has been programmed to use.

In the absence of a sorting function, .sort will sort the items as strings - this is just an arbitrary point of the design. Ideally you should be passing a function to be used whenever you want to .sort things, as is the case here where the function forces the values to be compared as numbers.

like image 185
Niet the Dark Absol Avatar answered Sep 25 '22 01:09

Niet the Dark Absol


For whatever reason (and I should find documentation) the default behavior for Array.prototype.sort is to sort by string, not numerically. That means that you have to define numeric sorting behavior.

  1. How do a and b get populated - Welcome to the world of functional programming. The array is iterated over internally and the callback function is called with a (first element) and b (second element) until the elements are exhausted. You don't have to worry too much about this, just know that that is what happens.

  2. The documentation on this is pretty clear, fortunately. If the return value of the callback is less than 0, a has a lower index than b. If 0 is returned, keep them at the same index relative to other elements. If a positive value is returned, b has a lower index than a. That means that a - b is guaranteed to work properly for numerical sorting. However, you will run into trouble with this callback function if there are any non-numeric elements. Only use it if you know for a fact that the array contains only numeric elements.

  3. This does a simple insertion sort and actually does not go two at a time, but will backtrack if b happens to be less than a. You can examine this behavior by adding a console.log(a,b) to the sort callback method.

like image 43
Explosion Pills Avatar answered Sep 25 '22 01:09

Explosion Pills