Sorting numbers within a JavaScript array

The problem

You need to sort this JavaScript array in numeric order:


var numbers = [2, 1, 11];

Arrays have a sort method, so lets try using that


var numbers = [2, 1, 11];

console.log(numbers.sort());

The output from running this in Chrome 67 is that the array is now sorted as:

[1, 11, 2]

Which is not what we want, the number 11 is in the wrong place.

The Reason

This result is produced because using the JavaScript sort() without a compare method array causes elements to be sorted by converting them to strings and comparing strings in Unicode code point order.

Apologies! That was a bit opaque so lets take that last paragraph apart. The sort method first converts the numbers to strings so we conceptually have

“2”, “1”, “11”

The  UTF-16 code for each of these are obtained and these are respectively

0032, 0031, 0031 0031

With both “1” and “11”  having a lower UTF-16 code than “2” it should now be slightly clearer why 11 appears before 2.

The Solution

The sort method compares two values to determine which should come first. These two values are usually referred to as a and b. The sort method can have an function, anonymous or named as a parameter. This function is a referred to as a compare function. The compare function allows you as the developer to define the rules for sorting.

The compare function should return a number. That number will be  used to determine which of a or b comes first.

<0

If the compare function returns less than zero a should be shown before b

0

If the compare function returns zero, the a and b should remain in the same order

>0

If the compare function returns greater than zero b should be shown before a

Shown below is an example of anonymous compare function:

function(a, b) {  

  return a - b; 

}

This function can then be passed to the sort() method as shown below. The calls to console.log are instrumentation that you can use to see what is going during each of the three times the compare function is invoked.

 

  var numbers = [2, 1, 11];
  console.log('Original order: ' + numbers);

  numbers.sort(function(a, b) {
   console.log(a + ' - ' + b + ' = ' + (a - b));
   return a - b;
  });   

  console.log('Expected order: ' + numbers);

Pasting this into the Chrome console window will produce the following output:

20180724_02 .JPG

Stepping through the output, first displayed is the array in it’s original order.

The next two lines shows the results of the compare function and in this invocation the parameters a and b have the values 2 and 1 respectively

2 – 1 = 1 means that the compare function returns a number greater than 0 so that 1(b) will be shown before 2 (a)

The next line shows that the and b values for the final invocation are now 2 and 11.      2 – 11 = -9 which means that the compare function this time return a number less than zero so that 2(a) will be displayed before 11(b)

The final line shows the results of the sort and now the numbers are sorted as expected.

Acknowledgements

Another plug for this wonderful book which was the inspiration for this page Javascript and JQuery book by Jon Duckett

 

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.