10

The JavaScript sort function which takes a parameter allows one to pass in a function.

For example:

var myarray=[25, 8, 7, 41]
myarray.sort(function(a,b){return a - b}) //Array now becomes [7, 8, 25, 41]

How is it that the code

function(a,b){
    return a - b
}

is interpreted to be ascending? It's supposed to be divided into three cases, < 0 , == 0, and > 0, but how does this make sense when a and b can be anything?

Thank You!

mathielo
  • 6,725
  • 7
  • 50
  • 63
Caffeinated
  • 11,982
  • 40
  • 122
  • 216

7 Answers7

9
var myarray=[25, 8, 7, 41]
myarray.sort(function(a,b){return a - b}) //Array now becomes [7, 8, 25, 41]

simply change that to

var myarray=[25, 8, 7, 41]
myarray.sort(function(a,b){console.log("comparing " + a + ", " + b);return a - b}) //Array now becomes [7, 8, 25, 41]

after you try the above code in the console log you will see the following result

var myarray=[25, 8, 7, 41]
    myarray.sort(function(a,b){console.log("comparing " + a + ", " + b);return a - b}) //Array now becomes [7, 8, 25, 41]

is interpreted to be ascending? It's supposed to be divided into three cases, <0 , ==0, and >0 ; but how does this make sense when a and b can be anything?

FIRST COMPARISON : 25,8

Now, lets answer your doubt of how it choses the value of a, b. When you run the code you see the first comparison is made between 25,8 and if result is positive then it means that 8 is smaller. So it simply re-orders it to 8, 25.

SECOND COMPARISON : 25,7

Next comparison is made between 25 , 7 and that is because if the result is negative then the third number will be put after 25 and the sorting of the three numbers would be done.

But the case is different, now as the result again comes a positive. The array yet re-orders itself to

8, 7, 25

after that it again performs the test until it finds that the condition is positive. So now it compares 8, 7 and the result is again negative.

The array again re-orders itself to

7, 8, 25

THIRD COMPARISON : 25, 41

Now, in this last comparison, the result comes as positive, which means that 41 is greater than 25.

hence the array reorders itself to

7,8,25,41
Sagar Munjal
  • 762
  • 11
  • 12
6

The function sort will call the compareFunction function multiple times and passes to items a and b to it. This will happen multiple times until the array is sorted.

The compare function should return:

  • 0 if a == b;
  • a positive number if a > b;
  • a negative number if b < a.

Now, let's have a look at the function in your code, we have a - b =:

  • 0 if a == b;
  • a positive number if a > b;
  • a negative number if b < a.

So it returns the expected result and the array will be sorted correctly.

For more information, have a look at the documentation.

sch
  • 27,436
  • 3
  • 68
  • 83
6

The reason answering your question is especially tricky, or at least in detail, is because there is no specification that says which sorting algorithm a browser should implement. So telling you specifically how it works on one browser may differ between browsers, or even change over time.

The gist of it is though, you want to think of "a" and "b" as being any two values. If you are returning the result of "a" - "b", then your sort goes in ascending order. If you do "b" - "a", then it is in descending order.

The neat thing about making your own sort functions, is that you can compare the value of "a" and "b" after processing them in a separate function. So lets say you want to sort by the Celsius values, but your array in only in Fahrenheit. You can do something like:

.sort(function(a,b){ return to_fahrenheit(a) - to_fahrenheit(b);}
GoldenNewby
  • 4,382
  • 8
  • 33
  • 44
3

The function takes 2 parameters (a,b). This function subtracts a from b and returns the result. If the return value is
Positive - a is a number greater than b
Negative - a is a number less than b
ZERO - a is equal to b

The behavior is different based on the browser: See the output generated by different browsers:

var numArray = [20,1,10,2,3];
numArray.sort(function(a,b) {
  document.write("a = " + a + ", b = " + b + "<br />");  
  return a-b}
  );

output on firefox :
a = 20, b = 1
a = 20, b = 10
a = 1, b = 10
a = 2, b = 3
a = 20, b = 2
a = 1, b = 2
a = 10, b = 2
a = 10, b = 3


output on chrome:
a = 20, b = 1
a = 20, b = 10
a = 1, b = 10
a = 20, b = 2
a = 10, b = 2
a = 1, b = 2
a = 20, b = 3
a = 10, b = 3
a = 2, b = 3

Hope this helps!!

Kapil
  • 191
  • 2
  • 5
2
var a = [5,2,1,3,9,6];

console.log(a.sort(function(a,b){console.log(a+"," +b); return a>b;}));

Result:
5,2 => create array [2,5]
5,1 => need to check 2 and 1. [2,5], [1,5]
2,1 => push 1 before 2? isOk? => OK [1,2,5]
5,3 => need to check 1,2 with 3 before 5 [1,2,5], [3,5] 
2,3 => push 3 after 2 and before 5 => OK [1,2,3,5]
5,9 => [1,2,3,5,9]
9,6 => [1,2,3,5,9], [6,9]
5,6 => [1,2,3,5,6,9]
Dang Cong Duong
  • 486
  • 6
  • 9
2

Its because if b is bigger than a, it will be less than 0. If a == b, it will return 0. Otherwise it will be a positive number.

Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
1

This is easier to understand with an example. Let's study each possible case:

  1. Let a=10 and b=20. So a - b is -10, and by convention we return a negative value if a < b, so we're good.
  2. Let a=20 and b=10. So a - b is 10, and by convention we return a positive value if a > b, so we're still good.
  3. Let a=10 and b=10. So a - b is 0, and by convention we return 0 if a == b, and everything works as expected!

In general: if a < b, a - b will always be negative; if a > b, a - b will always be positive; and if a == b, a - b will always be 0, as long as a and b are integer values.

Óscar López
  • 232,561
  • 37
  • 312
  • 386