Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is this Array.sort behaviour different in Chrome vs Node.js

Problem

Let's make a basic list and sort it to make sure that 2 is ALWAYS first in the list. Simple enough, right?

[1, 2, 3].sort((a, b) => {
  if (a === 2) return -1;
  return 0;    
});

Chrome result: ✓

[2, 1, 3]

Node result: X

[1, 2, 3]

In order to get this behaviour in Node, you could - weirdly enough - look at the b parameter and make it return 1 if it's 2:

[1, 2, 3].sort((a, b) => {
  if (b === 2) return 1;
  return 0;    
});

With this implementation you get the opposite result; Chrome will be [1, 2, 3] and Node will be [2, 1, 3].

Questions

Do you have a logical explaination for this behaviour? Is my sorting function conceptually flawed? If so, how would you write this sorting behaviour?

like image 503
Fredrik Schön Avatar asked May 05 '19 18:05

Fredrik Schön


People also ask

What sort algorithm does chrome use?

Chrome uses a stable sorting algorithm for arrays of length < 10, but for arrays of more than ten items, it uses an unstable QuickSort algorithm.

Is JavaScript array sort stable?

Since version 10 (or ECMAScript 2019), the specification dictates that Array.prototype.sort is stable.

How do you sort an array in node JS?

sort() is an array function from Node. js that is used to sort a given array. Parameter: This function does not takes any parameter. Return type: The function returns the sorted array.


1 Answers

Do you have a logical explaination for this behaviour?

Browsers use different sorting methods. Therefore they possibly call the provided callback with different arguments in a different order. If your sort function is not consistent, the sorting won't be stable. This will lead to a wrong sort order (it also always would with different input arrays, so your sorting will never really work).

If so, how would you write this sorting behaviour?

Make sure that these two conditions apply to every possible input:

1) Two equal elements should not be sorted:

  sort(a, a) === 0

2) If the sort function gets called in inversed order, the result is also inversed:

  sort(a, b) - sort(b, a) === 0

In your case, both are not fullfilled:

  sort(2, 2) // 1 -> wrong!
  sort(2, 3) - sort(3, 2) // 1 -> wrong!

To write a stable sort, you have to look at a and b:

  function(a, b) {
    if(a === 2 && b === 2)
      return 0;
    if(a === 2)
      return 1;
    if(b === 2)
      return -1;
    return 0;
  }

Or to make that shorter:

  (a, b) => (a === 2) - (b === 2)
like image 139
Jonas Wilms Avatar answered Nov 14 '22 23:11

Jonas Wilms