6
var arr = [5, 2, 1, -10, 8];

arr.sort(function(a, b) {
  console.log(a,b)
  return b - a;

}) ; // 8, 5, 2, 1, -10

How does this callback work?

What is the principle of choice a and b?

Please explain this particular example from the inside.

output console.log (at first, please explain this output ):

  5 2
  2 1
  1 -10
 -10 8
  1 8
  2 8
  5 8
Oksana
  • 300
  • 2
  • 9
  • if it return +ve then swap otherwise not . ? – Mahi Dec 13 '16 at 12:24
  • 1
    I'm confused, what you exactly want – Josh Lin Dec 13 '16 at 12:30
  • Also, further reading to what Pablo supplied: http://stackoverflow.com/questions/24080785/sorting-in-javascript-shouldnt-returning-a-boolean-be-enough-for-a-comparison/24080786#24080786 – VLAZ Dec 13 '16 at 12:32
  • It works the way the [documentation](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#Description) describes it. –  Dec 13 '16 at 13:35
  • *please explain this output* It is the engine enquiring as to the order of various pairs. The engine makes the optimal number of comparisons between items to allow it to sort the input. –  Dec 13 '16 at 13:45

3 Answers3

20

It depends on the implementation. This actual implementation, looks like an insertion sort, with this amount of data (it could be different, like with Chrome, and the different implementation for less than 10 items or more items), is going from index zero to the end and if a swap has not taken place at the last two items, then it stops, otherwise it goes backwards to index zero.

Basically it tests and changes in this order

5   2   1 -10   8   original order
5   2
    2   1
        1 -10
          -10   8   swap
            8 -10
        1   8       swap
        8   1
    2   8           swap
    8   2
5   8               swap
8   5  2    1 -10   result

A more complex sorting shows better what is going on, with two greater values, which need to move to the other side of the array

8   9   1   2   3   4   original array
8   9
    9   1               swap
    1   9
8   1                   swap
1   8
        9   2           swap
        2   9
    8   2               swap
    2   8
1   2
            9   3       swap
            3   9
        8   3           swap
        3   8
    2   3
                9   4   swap
                4   9
            8   4       swap
            4   8
        3   4
1   2   3   4   8   9   result

Live example, does not work in all user agents (eg not in Edge, but in Chrome)

var array = [8, 9, 1, 2, 3, 4];
console.log(JSON.stringify(array));
array.sort(function (a, b) {
    console.log(a , b, JSON.stringify(array));
    return a - b;
});
console.log(JSON.stringify(array));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • They want to know WHY, not how. – Feathercrown Dec 13 '16 at 12:36
  • @Feathercrown, i read *"how is sort(compareFunction) works?"* – Nina Scholz Dec 13 '16 at 12:37
  • Well, their question originally asked why, regardless of the title, but they changed it anyways. – Feathercrown Dec 13 '16 at 12:42
  • Your answer *correctness* depends on sorting algorithm used by browser and nature of data itself, so in one browser it may be correct, in other taken actions may differ. – Justinas Dec 13 '16 at 12:44
  • @Justinas, yes, please see edit. – Nina Scholz Dec 13 '16 at 12:48
  • @NinaScholz I have never seen a clearer example of a duplicate. –  Dec 13 '16 at 13:43
  • @torazaburo, and now? – Nina Scholz Dec 13 '16 at 13:46
  • *It depends on the implementation* I'm puzzled as to why you would say this. The semantics of the comparison function are identical for any implementation. What the engine *does* with the results of the comparison will depend on the specific algorithm it chooses, but as far as I can tell that was not the question. –  Dec 13 '16 at 13:49
  • If you mean "so what", the answer is that you should find the duplicate and vote to close this one in favor of that one. –  Dec 13 '16 at 14:08
5

.sort() with custom function must return number indicating witch item must be placed in front:

< 0 - First element must be placed before second
   0 - Both elements is equal, do not change order.
> 0 - Second element must be placed before first.


Usually b - a means descendant sorting while a - b means ascendant ordering.


What algorithm is used to sort elements depends on browser implementation of .sort. Check comparison of them:

enter image description here

Justinas
  • 41,402
  • 5
  • 66
  • 96
  • `< 0 - First element must be placed before second` does that mean do not change the order ? – Mahi Dec 13 '16 at 12:31
  • 1
    I can look at these gifs for hours :) Cool example. – Timmetje Dec 13 '16 at 12:33
  • @Timmetje what can you learn by these gif ? – Mahi Dec 13 '16 at 12:34
  • @Mahi How data effects speed of sort compared when using different algorithms. – Justinas Dec 13 '16 at 12:35
  • @Justinas ok whatever . please answer my first question in comment section . – Mahi Dec 13 '16 at 12:36
  • 1
    @Mahi for example - selection sort has the same performance regardless of the dataset, bubble sort has worse performance with a reversed dataset, for a nearly sorted dataset shell sort is quite fast, etc. Also, it's just neat to look at. – VLAZ Dec 13 '16 at 12:37
  • Visualizing different algorithms makes a simple understanding on how they loop they array and what happens. Look at this for example: https://visualgo.net/sorting Also benchmarking is cool visualized: https://www.youtube.com/watch?v=ZZuD6iUe3Pc – Timmetje Dec 13 '16 at 12:37
  • 2
    @Mahi No, if some algorithm takes `a` that is located after `b` and it must be swapped in places – Justinas Dec 13 '16 at 12:37
  • 1
    @Timmetje Check this: https://www.youtube.com/watch?v=kPRA0W1kECg – Justinas Dec 13 '16 at 12:40
  • In stead of working I am on YouTube watching sorting mechanisms again. Thanks :) – Timmetje Dec 13 '16 at 12:50
  • @Timmetje http://imgur.com/gallery/dYgFh :) – VLAZ Dec 13 '16 at 13:01
  • *Both elements are equal, do not change order.* This is incorrect. It does not mean that the elements are equal, just that they should be sorted as if they were. Also, the spec does not require the sort to be "stable", meaning that `a` could come either before or after `b`, as long as they are together. –  Dec 13 '16 at 13:36
0

It will sort the item by the subtracted value by moving it that value lower or higher.

Here is some info:

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

If compareFunction is supplied, the array elements are sorted according to the return value of the compare function. If a and b are two elements being compared, then:

  • If compareFunction(a, b) is less than 0, sort a to a lower index than b, i.e. a comes first.
  • If compareFunction(a, b) returns 0, leave a and b unchanged with respect to each other, but sorted with respect to all different
    elements. Note: the ECMAscript standard does not guarantee this
    behaviour, and thus not all browsers (e.g. Mozilla versions dating
    back to at least 2003) respect this.
  • If compareFunction(a, b) is greater than 0, sort b to a lower index than a.
  • compareFunction(a, b) must always return the same value when given a specific pair of elements a and b as its two arguments. If inconsistent results are returned then the sort order is undefined.

So, the compare function has the following form:

function compare(a, b) {
  if (a is less than b by some ordering criterion) {
    return -1;
  }
  if (a is greater than b by the ordering criterion) {
    return 1;
  }
  // a must be equal to b
  return 0;
}

To compare numbers instead of strings, the compare function can simply subtract b from a. The following function will sort the array ascending (if it doesn't contain Infinity and NaN):

function compareNumbers(a, b) {
  return a - b;
}
Timmetje
  • 7,641
  • 18
  • 36
  • `If compareFunction(a, b) is less than 0, sort a to a lower index than b, i.e. a comes first.` does that mean don't do anything ? – Mahi Dec 13 '16 at 12:38
  • Yep it will skip and checks the next values. For example [4,4,6] The first two are 0 so it doesn't move them. The last pair are 4, 6 and it will be 4-6=-2 So it will Move the 4 up the array, it will continue to do this until your array is [6,4,4] – Timmetje Dec 13 '16 at 12:39
  • so can sort function can be converted to `if it return +ve then swap otherwise not . ? ` – Mahi Dec 13 '16 at 12:40
  • If it does anything with the value is also determined by the algorithm, but it won't necessary swap. In this case if + it will lower A and if - it will lower B. But at least it will lower A or it will lower B. the only thing when doing nothing is 0. – Timmetje Dec 13 '16 at 12:49
  • @Mahi no, you can't change it without losing some of the sorting functionality. JS can infer things about your dataset, so it doesn't need to do all comparisons, consider `1, 2, 3` - if it compares `1, 2` it will find that `1 < 2` if it compares `2, 3` it will find that `2 < 3` with these two facts together, it can skip checking `1, 3` as it's already implicit that `1 (< 2) < 3`. If your sorting algorithm says that 2 and 3 are equal (`return 0`) then the information derived from sorting may also be incorrect, depending on how the dataset is traversed - You may end up an array of `[2, 1, 3]`. – VLAZ Dec 13 '16 at 13:10
  • Please provide the reference for your "some info". Also, I think the array will be sorted just fine if it contains `Infinity`--why wouldn't it be? Finally, your comment *// a must be equal to b* is incorrect--it means that `a` and `b` should be sorted as if they were identical, not that they are equal. –  Dec 13 '16 at 13:38
  • Its all directly from https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/sort Edited accordingly Also the comment of Mozilla is correct for example: `if (" " > 0)` is not identical but it will return 0. – Timmetje Dec 13 '16 at 14:16
  • Infinity doesn't work because it would order lexicographically. Try out `[-Inifinity, -1, 1, Infinity]` the outcome with sort would be incorrect.It all seems to be correct still and answering the question. You even linked the documentation yourself. – Timmetje Dec 13 '16 at 14:24