最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Why is this Array.sort behaviour different in Chrome vs Node.js - Stack Overflow

programmeradmin1浏览0评论

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?

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?

Share Improve this question asked May 5, 2019 at 18:46 FredrikFredrik 5,1081 gold badge23 silver badges32 bronze badges 9
  • 1 My firefox Quantum also returns [1,2,3] – Some random IT boy Commented May 5, 2019 at 18:50
  • 6 Add both if (a === 2) return -1; if (b === 2) return 1; to the pareFunction. If you add a console.log(a,b) inside the function, you should see different logs for chrome and node – adiga Commented May 5, 2019 at 18:50
  • 5 The parison function must correctly return 0, or a value < 0 or > 0. Your parison incorrectly declares values equal that aren't equal, so the oute is random for all intents and purposes. There's also no reason why a or b specifically can be expected to be 2. – deceze Commented May 5, 2019 at 18:54
  • 4 The .sort() callback must be consistent: the result for pare(a, b) and pare(b, a) have to make sense. – Pointy Commented May 5, 2019 at 18:55
  • 4 "pareFunction(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." – str Commented May 5, 2019 at 18:55
 |  Show 4 more ments

1 Answer 1

Reset to default 10

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)
发布评论

评论列表(0)

  1. 暂无评论