array.sort()方法中反向比较函数的逻辑

时间:2015-12-04 16:24:42

标签: javascript

现在我知道这对许多人来说是一个愚蠢的问题,但我无法理解这个逻辑。所以,这就是问题所在:

var points = [40, 100, 1, 5, 25, 10];
points.sort(function(a, b){return a-b});

现在假设,比较值40和100,因此比较函数返回负值,即-60。因此,40位于100之前。理解。

现在,我这样做:

var points = [40, 100, 1, 5, 25, 10];
points.sort(function(a, b){return b-a});

同样,如果比较100和40,比较函数返回一个正值,即60.现在,它不应该在40之后放置100,因为该正值返回值?但它没有,我没有得到它。

我只是想知道这里发生了什么。

5 个答案:

答案 0 :(得分:3)

From the Mozilla documentation

  

如果提供compareFunction,则对数组元素进行排序   根据比较函数的返回值。如果a和b是   比较两个要素,然后:

     

如果compareFunction(a,b)小于0,则将a排序为低于的索引   b,即a先来。   如果compareFunction(a,b)返回0,则保留a和   b相对于彼此保持不变,但相对于所有人排序   不同的元素。注意:ECMAscript标准不保证   这种行为,因而并非所有浏览器(例如Mozilla版本   可以追溯到至少2003年)尊重这一点。

     

如果compareFunction(a,b)   如果大于0,则将b排序为低于。

的索引      

的compareFunction(一,   b)给定一对特定的一对时,必须始终返回相同的值   元素a和b作为它的两个参数。如果结果不一致   返回后排序顺序未定义。

想象一下,您的数组只有两个项目:10060。会发生的情况是,当10060进行比较时,函数会返回40,这是一个正值。当60100进行比较时,函数返回-40这是一个负值...这就是sort知道每个元素的放置位置的方式。

也许您会感到困惑,因为您不了解排序算法如何在内部工作,如果是这样的话,请看看这些

答案 1 :(得分:2)

您的比较函数完全正确 - 您正在使用减法,这与分支相比非常快,实际上是比较两个整数值时典型处理器的功能。基本上:

  • 如果您的比较函数返回0,则两者的顺序无关紧要。
  • 如果你的比较函数返回小于0(无关紧要),第一个参数应该在第二个参数之前。
  • 如果你的比较函数返回大于0(再次,无关紧要),第二个参数应该在第一个参数之前。

最后一点是你在逻辑上感到困惑的地方 - 在你的脑海中,你把值的顺序翻转到“之前”到“之后”,这使得语句回来了再次到第一个。 :)记住 - 参数的名称或函数中发生的任何事情无关紧要 - 它只是函数参数中的 order ,并返回相应的结果。

答案 2 :(得分:1)

请注意,您的比较函数不能保证每个数组的条目只调用一次,并且肯定在线性时间内完成(O(n)),但取决于算法,它最多是O(n log n)

我的意思是,40不仅会被比较为100,还会被比作1和5等等。所以你(人类)无法真正预测到100 - 40会将它排序您希望它在比较之后的特定方式(每个值发生几次比较),因为有几个步骤可以确定每个值的最终索引。

答案 3 :(得分:1)

在功能上,(忽略最大值出现整数溢出的事实),升序(a-b)会发生什么,等同于以下内容。

var ascSort = function(a, b) {
    if (a > b) { 
        return 1;
    }  else if (a < b) {
        return -1;
    } else {
        return 0;
    }
}

降序,只是否定返回值以翻转排序

var descSort = function(a, b) {
    if (a > b) { 
        return -1;
    }  else if (a < b) {
        return 1;
    } else {
        return 0;
    }
}

所以你现在可以做到

[40, 100, 1, 5, 25, 10].sort(ascSort); // [1, 5, 10, 25, 40, 100]
[40, 100, 1, 5, 25, 10].sort(descSort); // [100, 40, 25, 10, 1] 

答案 4 :(得分:1)

  

根据sort()的定义,方法是对数组中的元素进行排序并返回数组。默认排序是根据字符串Unicode代码点。

比较pudocode看起来像:

g.updateOptions({
  dateWindow: [minDateInMillis, maxDateInMillis],
  valueRange: [yAxisMin, yAxisMax]
});

比较数字:

function compare(a, b) {
  if (a is less than b by some ordering criterion) {
     return -1;
  }
  if (a is greater than b by the ordering criterion) {
    return 1;
  }
  // a must be equal to b
  return 0;
}