现在我知道这对许多人来说是一个愚蠢的问题,但我无法理解这个逻辑。所以,这就是问题所在:
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,因为该正值返回值?但它没有,我没有得到它。
我只是想知道这里发生了什么。
答案 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作为它的两个参数。如果结果不一致 返回后排序顺序未定义。
想象一下,您的数组只有两个项目:100
和60
。会发生的情况是,当100
与60
进行比较时,函数会返回40
,这是一个正值。当60
与100
进行比较时,函数返回-40
这是一个负值...这就是sort
知道每个元素的放置位置的方式。
也许您会感到困惑,因为您不了解排序算法如何在内部工作,如果是这样的话,请看看这些:
答案 1 :(得分:2)
您的比较函数完全正确 - 您正在使用减法,这与分支相比非常快,实际上是比较两个整数值时典型处理器的功能。基本上:
最后一点是你在逻辑上感到困惑的地方 - 在你的脑海中,你把值和的顺序翻转到“之前”到“之后”,这使得语句回来了再次到第一个。 :)记住 - 参数的名称或函数中发生的任何事情无关紧要 - 它只是函数参数中的 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;
}