Javascript Array.prototype.sort() method, anyone?

Javascript Array.prototype.sort() method, anyone?
0

#1

Can any one explain how this method works for sorting an array of digits?

array.sort(function(a,b){
  return b - a;
}); //[21, 12, 2, 1]

I have looked at the docs:
but I don’t understand how the return b-a works. I cannot get how returning -1, 1 or 0 sorts the array.


#2

Look for the compare function in the link you provided - docs.

It is explained how does the sort function works. I added comments for better understanding.

function compare(a, b) {
  if (a is less than b by some ordering criterion) {
//if you want to put smaller number at the end of the array, to get an array with descending order return a negative number
    return -1;
  }
  if (a is greater than b by the ordering criterion) {
//if you want to put smaller number at the begining of the array, , to get an array with descending order return a postive number
    return 1;
  }
  // a must be equal to b
  return 0;
}

So b-a, will return a positive number if b is greater than the a, and negative if a is greater than b. A and b here are two elements of the array that go into comparison. Sort method will iterate trough entire array, using the compare function that you provided.


#3

Thanks for the quick response. I am still having trouble visualizing.

Ex.
[2, 1, 3],

first comparison is return b - a, is that 1 - 2 to return -1?
and if so how does the returned value (-1) determine the order?

I assume that it would be no change then go on to 3 - 1 to return 1, the change is made [ 2, 3, 1], then what?


#4

Sort order is determined just as VukMNE has described above. If the result of the compare is negative then the right hand side (b) must be smaller than the left hand side (a) and thus they are out of order. If the array were just [2, 2] you’d get ‘0’ meaning they are equal (the last segment quoted above). Since the last condition 3 - 2 is positive one, at least if you are sorting in ascending order b is greater than a and it can stay in the same place.

Obviously if you were sorting in descending order these conditions would be reversed (i.e. if result is negative, don’t swap, if it is positive, swap).

One other thing to note-- A quick look and it is not clear to me exactly what sort algorithm they are using under the hood here, but presumably the sort function will run through the array on multiple passes until every element in the array meets the specified condition [i.e. since the compare is on a,b adjacent terms some sorts would require multiple swaps to put them in the right place].


#5

@abalducci You’re right about the callback possibly running multiple times per element, this is also mentioned at the very bottom of the MDN docs for sort


#6

btw if you use a > b or a < b in the callback function it can both sort numbers and strings alphabetically, a - b and b - a can’t sort strings properly


#7

Whenever I am confused about how something works, I just start sticking in console.log statements and stepping though it. This:

[NOTE: Heavily edited based on sfiquet’s corrections.]

const arr = [2, 1, 3];

console.log('********** arr before sort...')
console.log(arr)

arr.sort(function(a, b) {
  console.log('\n\n*** entering sort function, arr is...');
  console.log(arr);
  console.log('comparing a=' + a + ' and b=' + b);
  if (a>b) {
    console.log('a is greater than b so return -1 (sort order correct)');
    return -1;
  }
  if (a<b) {
    console.log('a is less than b so return 1 (sort order incorrect)');
    return 1;
  }
  console.log('a is equal to b so return 0 (sort order irrelevant)');
  return 0;
});
         
console.log('\n\n********** arr after sort');
console.log(arr);

yields the results:

********** arr before sort...
(3) [2, 1, 3]

*** entering sort function, arr is...
(3) [2, 1, 3]
comparing a=2 and b=1
a is greater than b so return -1 (sort order correct)

*** entering sort function, arr is...
(3) [2, 1, 3]
comparing a=1 and b=3
a is less than b so return 1 (sort order incorrect)

*** entering sort function, arr is...
(3) [2, 1, 1]
comparing a=2 and b=3
a is less than b so return 1 (sort order incorrect)


********** arr after sort
(3) [3, 2, 1]

To reiterate what others have said, the 1 (or any positive number) tells it the sort is incorrect, a 0 means the they are the same so it is irrelevant, and a -1 (or any negative number) tells it the sort order is correct. Subtracting is just a different way or comparing numbers, but as pointed out, it only works for numbers.

Here is a link to the pen so you can mess around with it yourself.


#8

That’s a nice learning tool Kevin.

Just for the sake of utter simplicity I would also add to ead’s comment, as from the MDN docs, if you want true ‘alphabetical order sort’ (assuming case and punctuation are removed), simply just array.sort() will work without need for any compare function.

From the MDN for sort:

Parameters
compareFunction Optional

Specifies a function that defines the sort order. If omitted, the array is sorted according to each character’s Unicode code point value, according to the string conversion of each element.

– Actually this will even work for the forward going numeric case too, by which after you could do just an Array.reverse() if you wanted descending order.

However it is useful to know the function form in the case you wanted your sort order to be based on some more complicated custom parameter.


#9

Just for the sake of utter simplicity I would also add to ead’s comment, as from the MDN docs, if you want true ‘alphabetical order sort’ (assuming case and punctuation are removed), simply just array.sort() will work without need for any compare function.

i know it but what if you want to sort not an array of strings but an array of objects or a nested array i.e. an array of arrays by the alphabetical order of a property of those objects or a value by one of the indexes in those inner arrays? btw in the challenge “inventory update” as one of the tasks you have to do exactly that, you have to alphabetically sort a nested array. so sometimes you still need callback to sort strings, you have to use for instance a[1] and b[1] there ofc, assuming you sort by the index 1 value

you also may save the anonymous callback as a separate function like
function mySort (a, b) {return a > b;}
and then you can use it like arr.sort(mySort) and the arr now can be both of numbers or of strings and it will be sorted properly anyway. tbh javascript had to make sort() work by default like that but w/e


#10

Sure, sure… It is just that I understand rkentmc’s basic confusion as to how such a formulation of a sort works. Sorting methods (as well as search) have classically been a huge topic in academic computing though so…

If a quick Google search on the topic proves at least somewhat accurate, the actual algorithm used by the .sort() method depends both on the set size (reasonable), but also on what the particular flavor of JS the browser/host is using.

Maybe sort a hundred, even a thousand things via just .sort() if it works for you without params, but when you get into really large sets you want to craft one of at least the traditional algorithms so at least you can place a known bounds on performance time…

I actually think rkentmc’s question is excellent in this way, as with any of the traditional algorithms, though with different criteria, you sort though the array/object any number of times until it is ordered. However FCC just presents this magical function ‘sort’, and really I can understand it is not at first obvious what might exactly be going on under the hood.


#11

Sorry if that sounds picky but the function you gave as an example will not work properly. It returns a boolean, i.e. true or false, which will convert to 1 and 0. The sort function needs to return -1, 0, or 1. The proper function would be something like:

function mySort(a, b){
  if (a < b) return -1;
  else if (a > b) return 1;
  else return 0;
}

Thought I’d mention it in case someone got confused.


#12

There’s something wrong with your function. The messages don’t match the code. It says the function return -1 when it returns 1 and vice versa (the part about sort order is correct though). I’m guessing you changed the code at some point but didn’t update the messages?

In any case that means your conclusion needs to be changed:

  • 1 means a is bigger than b so a swap is needed
  • -1 means a is smaller than b so they are already in the right order.
  • 0 means they are the same

#13

ive seen that sort function before, and I spent hours trying to figure out what was going on. So I made an array, I used it, then on paper I drew out the same array and tried to match what was happening.

so we have this array [10,20,15,30,0]
sooooo…how to get this in order.
remember the computer cant just swt aside thought like we can it has to do it in an order.
so it looks at its steps
step 1:is arr[0] bigger than arr[1]? no everything stays
step 2: is arr[1] bigger than arr[2]? yes so we swich them
step 3:is arr[2] bigger than arr[3] no everything stays
step 4: is arr[3] bigger than arr[4]? yes so we switch them.

so now we have a slightly different array.
[10,15,20,0,30] closer right. well the sort function repeats itself until nothing is changed.
so I goes through the whole steps again.
so it will go again to get
[10,15,0,20,30]
[10,0,15,20,30]
then finaly
[0,10,15,20,30]

so whats the a-b thing?
well if a is bigger than b its a positive number and should not be moved.(like arr[0]-arr[1]
if a is smaller than b then it will return a negative number and should be switched(like arr[4] -arr[3]

a-b makes it go low to high, it tells it to switch if a and b if b is bigger.
b-a makes it go high to low.

to really see how it goes, just put return -1; instead a-b;
watch how they shift. thw whole thing will switch until it reaches the end of the array.
sort is just looking for a thumbs up or a thumbs down, the a-b is either negative or positive.


#14

Yes, you’re right, good catch. I’ve made some corrections.