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

google chrome - Sort undefined value in javascript works incorrectly - Stack Overflow

programmeradmin0浏览0评论

I have an array of object like:

var arr = [{index: 1, key: undefined}, {index: 2, key: undefined},{index: 3, key: undefined},{index: 4, key: undefined},{index: 5, key: undefined},{index: 6, key: undefined},{index: 7, key: undefined},{index: 8, key: undefined},{index: 9, key: undefined},{index: 10, key: undefined},{index: 11, key: undefined},{index: 12, key: undefined},{index: 13, key: undefined},{index: 14, key: undefined},{index: 15, key: undefined},{index: 16, key: undefined},{index: 17, key: undefined},{index: 18, key: undefined},{index: 19, key: undefined} ]

I want to sort array arr by key - here is all undefined value. The return value should be the same as arr. But when i execute:

arr.sort(function(a,b){return a.key - b.key})

The result is not the same as i expected, the array order is changed. Any idea on this problem?

My result: .jpg

Update: Tested with another array:

var b = [{index: 1, key: 10}, {index: 2, key: 10},{index: 3, key: 10},{index: 4, key: 10},{index: 5, key: 10},{index: 6, key: 10},{index: 7, key: 10},{index: 8, key: 10},{index: 9, key: 10},{index: 10, key: 10},{index: 11, key: 10},{index: 12, key: 10},{index: 13, key: 10},{index: 14, key: 10},{index: 15, key: 10},{index: 16, key: 10},{index: 17, key: 10},{index: 18, key: 10},{index: 19, key: 10} ]

Every key has same value, but when sort function is call: .jpg

IE and Firefox is work OK, the problem happens in Chrome. I guess something go wrong with the case return 0.

I have an array of object like:

var arr = [{index: 1, key: undefined}, {index: 2, key: undefined},{index: 3, key: undefined},{index: 4, key: undefined},{index: 5, key: undefined},{index: 6, key: undefined},{index: 7, key: undefined},{index: 8, key: undefined},{index: 9, key: undefined},{index: 10, key: undefined},{index: 11, key: undefined},{index: 12, key: undefined},{index: 13, key: undefined},{index: 14, key: undefined},{index: 15, key: undefined},{index: 16, key: undefined},{index: 17, key: undefined},{index: 18, key: undefined},{index: 19, key: undefined} ]

I want to sort array arr by key - here is all undefined value. The return value should be the same as arr. But when i execute:

arr.sort(function(a,b){return a.key - b.key})

The result is not the same as i expected, the array order is changed. Any idea on this problem?

My result: https://i.sstatic/ksCQ5.jpg

Update: Tested with another array:

var b = [{index: 1, key: 10}, {index: 2, key: 10},{index: 3, key: 10},{index: 4, key: 10},{index: 5, key: 10},{index: 6, key: 10},{index: 7, key: 10},{index: 8, key: 10},{index: 9, key: 10},{index: 10, key: 10},{index: 11, key: 10},{index: 12, key: 10},{index: 13, key: 10},{index: 14, key: 10},{index: 15, key: 10},{index: 16, key: 10},{index: 17, key: 10},{index: 18, key: 10},{index: 19, key: 10} ]

Every key has same value, but when sort function is call: https://i.sstatic/Usar5.jpg

IE and Firefox is work OK, the problem happens in Chrome. I guess something go wrong with the case return 0.

Share Improve this question edited Mar 2, 2018 at 4:14 vicnoob asked Mar 2, 2018 at 3:16 vicnoobvicnoob 1,18313 silver badges27 bronze badges 5
  • Looks the same on my end – Eddie Commented Mar 2, 2018 at 3:18
  • imgur./a/4NyDq Here is my result – vicnoob Commented Mar 2, 2018 at 3:20
  • @Eddie Please try in chrome – vicnoob Commented Mar 2, 2018 at 3:41
  • Possible duplicate of Sorting an array of objects in Chrome – roomcayz Commented Mar 2, 2018 at 4:06
  • @vicnoob: can you select an answer for this question? thanks – Carloluis Commented Mar 13, 2018 at 0:31
Add a ment  | 

3 Answers 3

Reset to default 2

The problem is related with the stability of algorithms used inside array.sort implementation which depends on the engine used to execute your javascript code.

Chrome uses Google’s V8 engine. V8's sort algorithm use a bination of insertion-sort and quick-sort. Check the actual implementation here.

Insertion-sort is used when the array is small (array.length <= 10), otherwise quick-sort is used. The second sorting algorithm is unstable, and don't provide any guarantee about preserving order of equivalent elements.

As conclusion, I include two tests (both using your initial parison function). Chrome's results:

  • the first sort is performed on 10 elements array (therefore, original order is preserved)
  • the second sort is performed on your original array with 19 elements (in this case there is no certainty about keeping original order, and that's why the array order is changed)

const small = [
  {index: 1, key: undefined}, 
  {index: 2, key: undefined},
  {index: 3, key: undefined},
  {index: 4, key: undefined},
  {index: 5, key: undefined},
  {index: 6, key: undefined},
  {index: 7, key: undefined},
  {index: 8, key: undefined},
  {index: 9, key: undefined},
  {index: 10, key: undefined}
];

// stable sort
small.sort(function(a,b){return a.key - b.key});
console.log(small);

var arr = [
  ...small,
  {index: 11, key: undefined},
  {index: 12, key: undefined},
  {index: 13, key: undefined},
  {index: 14, key: undefined},
  {index: 15, key: undefined},
  {index: 16, key: undefined},
  {index: 17, key: undefined},
  {index: 18, key: undefined},
  {index: 19, key: undefined}
];

// unstable sort
arr.sort(function(a,b){return a.key - b.key});
console.log(arr);

Probably you need to implement a stable sorting algorithm to ensure your code will behave the same despite the environment in which will be executed. The most mon stable algorithms are bubble-sort, insertion-sort and merge-sort.

Read more about stability in sorting algorithms

Check chromium bug: V8 doesn't stable sort

Javascript engines. More.

Do the following....

arr.sort(function(a,b){return (!a || !b)? 0 : (a.key - b.key) })

What you are trying to do is to subtract undefined from undefined, and the result is NaN.

NaN < 0
> false

NaN > 0
> false

NaN is not -1 neither is 1, and it is not greater nor lesser than 0, so it seems to be treated as 0.

I'm not sure if the above sentence is true.

According to MDN:

If pareFunction(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.

So I've tested this in Firefox and the order stay unchanged. But doing the same in Chrome reproduced your problem.

发布评论

评论列表(0)

  1. 暂无评论