【问题标题】:Javascript Sorting - Strange behaviour, any idea?Javascript 排序 - 奇怪的行为,知道吗?
【发布时间】:2016-05-04 07:01:57
【问题描述】:

如果我这样做了

['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'k'].sort( function(a,b){ return a.length - b.length } )

输出

[“a”、“b”、“c”、“d”、“e”、“f”、“g”、“h”、“i”、“k”]

但是当我这样做时(最后添加了一个元素'l')

['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'k', 'l'].sort( function(a,b){ return a.length - b.length } )

输出

[“f”、“a”、“c”、“d”、“e”、“b”、“g”、“h”、“i”、“k”、“l”]

发生这种情况是否有任何具体原因,或者这只是一个怪癖?

PS:与this question相关。我在 chrome 上对其进行了测试,从昨天开始就一直困扰着我 :)

【问题讨论】:

  • @Alnitak 抱歉,我已经解释了数组之间的区别
  • 我猜?它在执行快速排序传递时将中间元素移到前面,然后使用插入排序退出/排序其余元素。
  • 奇怪的是,如果我使用 1..9 比较器对 1..9 进行排序,我看不到这种行为
  • 无论如何,排序后相等元素的顺序是不确定的。
  • @Alnitak 尝试 0..11。 IIRC,至少一个库排序实现使用,事实上的标准是插入最多 10 个元素的子数组和上面的快速排序。

标签: javascript arrays sorting


【解决方案1】:

我没有在当前的 V8 代码中找到章节,但this bug ticket 说 Chrome 对长度

插入排序算法是稳定的,也就是说,给定两个相等的元素,它将保留它们在数组中的相对位置。另一方面,快速排序算法是不稳定的 - 它会在随机相对位置留下相等的元素。

这都是可以的per the specification:

排序不一定是稳定的(即比较相等的元素不一定保持原来的顺序)

用户不得依赖于确定性的排序顺序。

【讨论】:

    【解决方案2】:

    您按照对所有值(即 1)都相同的标准(长度)进行排序。因此,任何订单都是正确排序的。如果输入已经排序,本机排序实现不保证保持顺序。

    【讨论】:

      【解决方案3】:

      该行为很可能是由实现引起的(例如快速排序)。但是请记住,javascript 在这里的行为是正确的。

      您的比较函数的合同规定,如果返回 0,则两个值相等并且它们的顺序无关紧要。 它并没有说它们应该保持相同的顺序。

      我为什么会得到这些结果的理论是快速排序在中间递归地将你的数组分成两半。对于偶数长度的数组和奇数长度的数组,这很可能会产生不同的结果。

      【讨论】:

      • 你应该测试一下这个理论——我的测试表明它是不正确的
      • 这就是为什么我说这是一个理论。要找出答案,您可能需要查看 JS 引擎实现的源代码。但话又说回来,根据规范,这种行为很好
      • 这是一个经过简单测试的理论,在您发布答案之前我已经这样做了(并排除了它)......
      【解决方案4】:

      这是因为在 JavaScript VM 中实现了 Quicksort。您的自定义函数在任何情况下都会返回 0,因为您的所有字符串长度都是 1,所以它基本上就像:

      ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'k'].sort( function(a,b){ return 0 } )

      【讨论】:

        猜你喜欢
        • 2011-03-13
        • 2012-12-17
        • 2011-03-06
        • 1970-01-01
        • 2011-02-17
        • 2019-01-18
        • 2023-03-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多