JavaScript数组排序出现奇怪的行为

3
我在尝试对JavaScript数组进行排序时遇到了奇怪的行为。

var arr = ['a', 'b', 'C', 'd', 'e', 'f', 'g', 'h', 'I', 'k'];

arr.sort(function (a, b) {
  console.log(a, b);
  if (a.length < b.length) return 1;
  else if (a.length > b.length) return -1;
  else return 0;
});

在这种情况下,它正常工作,将相同的数组返回给我。 控制台显示如下:

enter image description here

但是当我尝试使用以下输入时,

var arr = ['a', 'b', 'C', 'd', 'e', 'f', 'g', 'h', 'I', 'k', 'l'];

给我这个。

enter image description here

我不太明白为什么会发生这种情况。
附注:我正在编写自定义排序,检查元素的长度,因为我需要一个根据长度排序其元素的数组。

尝试 return a.length - b.length - Isaac
此外,所有这些长度都将是1... 尝试使用console.log()输出一些变量。 - Isaac
3
你可能需要一个稳定的排序算法,例如https://dev59.com/qnM_5IYBdhLWcg3wUxZB。 - fgb
5
JavaScript 的排序不保证稳定性,即如果自定义的排序函数对两个元素返回 0,则引擎可以任意放置它们的顺序。详见 https://dev59.com/QnA75IYBdhLWcg3w790Y - JJJ
在 MDN 的 Array.prototype.sort() 第二项中指出:如果 compareFunction(a, b) 返回 0,则相对于所有不同的元素,保持 a 和 b 不变,但已排序。注意:ECMAscript 标准不保证此行为,因此并非所有浏览器(例如至少可以追溯到 2003 年的 Mozilla 版本)都支持此行为。 因此,与 Chrome 或 Opera 不同,如果在 Firefox 中尝试您的示例,则会返回相同的数组。 - Redu
显示剩余2条评论
1个回答

2
ECMAScript没有规定特定的算法,也不指望它是稳定的(Array.prototype.sort)。稳定的排序算法可以维护元素的相对顺序,这些元素看起来是“相同的”。对于Array#sort,当比较函数返回0时,两个项目看起来是相同的。虽然InsertionSort和MergeSort(Apple和Mozilla)是稳定的,但QuickSort(Google Chrome)不是(Issue 90)。如果数组有10个或更少的元素,Chrome将使用InsertionSort对数组进行排序。

因此,在需要时,您可以自己实现稳定的算法,例如MergeSort。

检查完整帖子在这里


此外,在您的排序方法中返回0不受所有浏览器支持。https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/sort - Jeremy J Starcher
1
@JeremyJStarcher:你对文档的解释有误。在比较函数中返回0绝对是必要的,而且所有浏览器都支持它。只有稳定行为不受所有浏览器支持;它们仍然会将相等的内容排序在一起。 - Bergi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接