Arr.sort((a,b) => a-b); explanation

Hello everybody, I’m just going throw algorithms and solved Where do I Belong algorithm. I did everything but I didn’t know how to sort by numbers to get a normal order and not to have 10 or 20 before 3 or 4. And I found arr.sort((a,b) => a-b); this code and it works but can somebody explain me what exactly (a,b) a-b do or check in this arrow function for me to better understand?

function getIndexToIns(arr, num) {
  // Find my place in this sorted array.
  arr.push(num);
  arr.sort((a,b) => a-b);
  num = arr.indexOf(num);
 
  
  return num;
}

getIndexToIns([40, 60], 50);
4 Likes

When you sort an array with .sort(), it assumes that you are sorting strings. When sorting numbers, the default behavior will not sort them properly.

The function that you pass tells how to sort the elements. It takes two parameters (a and b) that represent any two elements from the array. How the elements will be sorted depends on the function’s return value:

  • if it returns a negative value, the value in a will be ordered before b.
  • if it returns 0, the ordering of a and b won’t change.
  • if it returns a positive value, the value in b will be ordered before a.

When you pass the function (a, b) => a - b, you’re telling the .sort() function to sort the numbers in ascending order.

3 Likes

Not sure if you are familiar with the arrow function syntax. Just in case, here’s a short explanation:
(a, b) => a - b is a shortcut notation for:

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

Function sort takes a comparison function as a parameter. This is what the sorting algorithm uses repeatedly to compare two elements in the array and decide which one goes to the left of the array and which goes to the right.

If you’re sorting numbers in ascending order, the smallest goes to the left. If you’re sorting in descending order, the biggest goes to the left.

The function needs to return -1 for a to be sorted to the left of b, 1 to be sorted to the right of b and 0 to be considered equal.

In this case a - b returns

  • a negative number if a is smaller than b – so a will be sorted to the left of b
  • a positive number if a is bigger than b – so a will be sorted to the right of b
  • zero if they are equal – so it doesn’t matter which one comes first

If you wanted to sort in descending order, i.e. bigger numbers first, you’d need your function to return b - a to invert the logic.

Using a comparison function also allows you to sort your numbers in a completely different way to serve your purpose. You could for instance sort all the odd numbers first then the even numbers (the example doesn’t care about the internal order within odd and even numbers):

function compare(a, b){
  let mod_a = a % 2;
  let mod_b = b % 2;
  return mod_b - mod_a;
}

And of course, this is not limited to numbers. You can sort just about any data with your own arbitrary criteria. For instance you can sort strings based on their lowercase value instead of the default Unicode, or ignore ‘a’ and ‘the’ at the beginning. You can sort an array of objects representing your music collection by artist, or by album name, or by date, or all of the above.

3 Likes

Thank you both for good answers :slight_smile:

I still don’t undestand how it work under the hood.
Let say I have arr = [1,20,10,5,2] and want to order it.
I will do arr.sort(function(a,b){return a-b}).
This will lead to [1,2,5,10,20] as the explanation up here say, if the result of a-b is negative a get first position, otherwise are swapped, if they are equal they stay in position.
Do javascript engine sort every time till there is no more swapping ?
1st round would do [1,20,10,5,2] checking a =1 and b =20.
2nd round would do [1,10,20,5,2] checkin a=20 and b = 10.
3rd round would do [1,10,5,20,2] checkin a= 20 and b = 5
4rd round would do [1,10,5,2,20] checkin a=20 and b =2
Array here is not yet sorted, does the engine do this all again ?
Where and how the engine know that the sorting is eneded ?
Now it should start over again:
[1,5,10,2,20]
[1,5,2,10,20]
and another time
[1,2,5,10,20]
END …
Is the path described what actually happend under the hood ? How to know it ?

`

Yes and no :slight_smile:
Steps you describe follow so called Bubble Sort algorithm - I almost guarantee no browser will implement it as it’s bad. In case of numbers, modern browser will most likely perform QuickSort, comparing values using function you’ve provided.

2 Likes

Thanks for the quick replay and the link to the QuickSort Algorithm which is well explained over there.
Still I ask myself If there is a way to look at which kind of code is being used under the hood or if it is completely hided from anyone.

You’re mistaking b for an index in the array whereas b is just a random number. So let’s say b = 6, it’ll check in the array [1, 20, 10, 5, 2] and if the value of a - b or
1 - 6 or (a[0] - b)
20 - 6 or (a[1] - b)
10 - 6 or (a[2] - b)
5 - 6 or (a[3] - b) and
2 - 6 or (a[4] - b)
are negative then it will put b (which = 6) to the right of this index (for instance when a[0] = 1). However, in the instance when a[1] = 20, a - b (20 - 6) will yield a positive number, therefore a (which = 20) will be placed to the right of b (which = 6). b is constant. So, in the original example that was posted:

getIndexToIns([40, 60], 50);

b will always be 50 in this example.

Hi and thanks for your time.
I don’t think your statement is right.
In the example you took from YariPL, the function he is providing is used to get the index in which you should insert the desired number into an array already set.
As you can see, 50 get pushed to the original array and then it get sorted.
Anybody feel free to correct me otherwise.

https://www.w3schools.com/jsref/jsref_sort.asp

Just use debugger and watch the values. It’s not top secret.

(() => {
    const sorted = [3,6,9,4,6].sort(function(a, b) {
        return a - b;
    });
    console.log(sorted);
})();

1st iteration:
a = 6, b = 3 // return 3

2nd iteration:
a = 9, b = 6 // return 3

3rd iteration:
a = 4, b = 9 // return -5

4th iteration:
a = 4, b = 6 // return -2

5th iteration:
a = 4, b = 3 // return 1

6th iteration:
a = 6, b = 6 // return 0

7th iteration:
a = 6, b = 9 // return -3

[ 3 ] [ 6 ] [ 9 ] [ 4 ] [ 6 ]
[ b ] [ a ] [ 9 ] [ 4 ] [ 6 ] ( 6-3 is positive ) (move b,a right)

[ 3 ] [ 6 ] [ 9 ] [ 4 ] [ 6 ]
[ 3 ] [ b ] [ a ] [ 4 ] [ 6 ] ( 9-6 is positive ) (move b,a right)

[ 3 ] [ 6 ] [ 9 ] [ 4 ] [ 6 ]
[ 3 ] [ 6 ] [ b ] [ a ] [ 6 ] ( 4-9 is negative )
[ 3 ] [ 6 ] [ 4 ] [ 9 ] [ 6 ] (swap b,a) (a remains 4 until a-b is positive, b is next value to left)

[ 3 ] [ 6 ] [ 4 ] [ 9 ] [ 6 ]
[ 3 ] [ b ] [ a ] [ 9 ] [ 6 ] ( 4 - 6 is negative)
[ 3 ] [ 4 ] [ 6 ] [ 9 ] [ 6 ] (swap b,a) (a remains 4 until a-b is positive, b is next value to left)

[ 3 ] [ 4 ] [ 6 ] [ 9 ] [ 6 ]
[ b ] [ a ] [ 6 ] [ 9 ] [ 6 ] ( 4 - 3 is positive) (return back to when a-b was last positive)

[ 3 ] [ 4 ] [ 6 ] [ 9 ] [ 6 ]
[ 3 ] [ 4 ] [ b ] [ 9 ] [ a ] (6 - 6 is 0) (keep same) (move right)

[ 3 ] [ 4 ] [ 6 ] [ 9 ] [ 6 ]
[ 3 ] [ 4 ] [ 6 ] [ b ] [ a ] ( 6 - 9 is negative)
[ 3 ] [ 4 ] [ 6 ] [ 6 ] [ 9 ] (swap)

completed.