﻿ JavaScript中的排序：不应该返回一个布尔值足以用于比较函数？ - 代码日志

#### JavaScript中的排序：不应该返回一个布尔值足以用于比较函数？

``````var arr = […] // some numbers or so
arr.sort(function(a, b) {
return a > b;
});
``````

TL; DR

I have always successfully sorted my arrays like this

``````> [1,1,0,2].sort(function(a, b){ return a>b })
Array [0, 1, 2, 1]
// in Opera 12. Results may vary between sorting algorithm implementations
``````

why?

JavaScript中的比较函数

How do comparison functions work?

`Array::sort` method可以采用可选的自定义比较函数作为其参数。该函数需要两个参数(通常称为a和b)，它应该比较，并且应该返回一个数字

>> 0当a被认为大于b并且应该在它之后排序
> == 0，当a被认为等于b，无论哪个先出现都无关紧要
>& 0当a被认为小于b并且应该在它之前排序

``````comp(a, b) == -1 * comp(b, a)
// or, if values other than -1, 0 and 1 are considered:
comp(a, b) * comp(b, a) <= 0
``````

If `comparefn` is […] not a consistent comparison function for the elements of this array, the behaviour of sort is implementation-defined.

A function `comparefn` is a consistent comparison function for a set of values `S` if all of the requirements below are met for all values `a`, `b`, and `c` (possibly the same value) in the set `S`: The notation `a <CF b` means `comparefn(a,b) < 0`; `a =CF b` means `comparefn(a,b) = 0` (of either sign); and `a >CF b` means `comparefn(a,b) > 0`.

Calling `comparefn(a,b)` always returns the same value `v` when given a specific pair of values `a` and `b` as its two arguments. Furthermore, `Type(v)` is Number, and `v` is not `NaN`. Note that this implies that exactly one of `a <CF b`, `a =CF b`, and `a >CF b` will be true for a given pair of `a` and `b`.

• Calling `comparefn(a,b)` does not modify the this object.
• `a =CF a` (07003)
• If `a =CF b`, then `b =CF a` (07004)
• If `a =CF b` and `b =CF c`, then `a =CF c` (07005 of `=CF`)
• If `a <CF b` and `b <CF c`, then `a <CF c` (transitivity of `<CF`)
• If `a >CF b` and `b >CF c`, then `a >CF c` (transitivity of `>CF`)

NOTE: The above conditions are necessary and sufficient to ensure that `comparefn` divides the set `S` into equivalence classes and that these equivalence classes are totally ordered.

Uh, what does this mean? Why should I care?

`````` function compare(a, b) { return Number(a > b); }
compare(0, 2) == 0 // ah, 2 and 0 are equal
compare(1, 0) == 1 // ah, 1 is larger than 0
// let's conclude: 1 is also larger than 2
``````

Ooops。这就是为什么当使用不一致的比较函数调用排序算法时，排序算法可能失败(在规范中，这是“实现相关的行为”，即不可预测的结果)。

Why is the wrong solution so common?

I have tested my comparison function, and it works!

``````function perms(n, i, arr, cb) {
// calls callback with all possible arrays of length n
if (i >= n) return cb(arr);
for (var j=0; j<n; j++) {
arr[i] = j;
perms(n, i+1, arr, cb);
}
}
for (var i=2; ; i++) // infinite loop
perms(i, 0, [], function(a) {
if (    a.slice().sort(function(a,b){ return a>b }).toString()
!= a.slice().sort(function(a,b){ return a-b }).toString() )
// you can also console.log() all of them, but remove the loop!
throw a.toString();
});
``````

``````function(a, b) {
if (a > b) return 1;
if (a < b) return -1;
/* else */ return 0;
}
``````

``````function(a, b) {
return a - b; // but make sure only numbers are passed (to avoid NaN)
}
``````

http://stackoverflow.com/questions/24080785/sorting-in-javascript-shouldnt-returning-a-boolean-be-enough-for-a-comparison