JS是否支持通过键函数而不是比较器进行排序?

时间:2018-10-06 21:35:47

标签: javascript sorting

JavaScript的array.sort方法采用一个可选的compare函数作为参数,该函数采用两个参数并确定其中一个小于另一个。

但是,有时使用 key函数自定义排序顺序会更方便,该函数将 one 值作为参数并为其分配一个排序键。例如:

textbox

JavaScript是否支持此功能,还是没有办法编写完善的比较功能?

4 个答案:

答案 0 :(得分:4)

您所描述的完全不支持 ,但是编写标准的.sort函数以最少的代码实现相同的目的很简单-只需返回差异在调用keyFunc的两个参数上调用sort之间:

function keyFunc(value){
    // complicated custom logic here, if desired
    return Math.abs(value);
}

myArr = [1, 3, -2];
myArr.sort((a, b) => keyFunc(a) - keyFunc(b));
console.log(myArr);
// the result should be [1, -2, 3]

如果键函数很复杂,并且您不想不必要地运行它,那么为每个输入创建一个查找表将非常简单,如果调用了keyFunc,则可以访问该查找表之前的值:

const keyValues = new Map();
function keyFunc(value){
    const previous = keyValues.get(value);
    if (previous !== undefined) return previous
    console.log('running expensive operations for ' + value);
    // complicated custom logic here, if desired
    const result = Math.abs(value);
    keyValues.set(value, result);
    return result;
}

myArr = [1, 3, -2];
myArr.sort((a, b) => keyFunc(a) - keyFunc(b));
console.log(myArr);
// the result should be [1, -2, 3]

答案 1 :(得分:1)

如上所述,您必须自己编写该功能或扩展当前数组sort方法等。

另一种方法是,如果您使用lodash及其orderBy方法...那么,它将变为:

myArr=[1, 3, -2];

const result = _.orderBy(myArr, Math.abs)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

答案 2 :(得分:0)

您可以轻松地从两个元素中减去“键”:

 myArr.sort((a, b) => keyFunc(a) - keyFunc(b));

您还可以猴子打sort

 {
   const { sort } = Array.prototype;
   Array.prototype.sort = function(sorter) {
    if(sorter.length === 2) {
      sort.call(this, sorter);
    } else {
       sort.call(this, (a, b) => sorter(a) - sorter(b));
    }
  };
}

然后:

 myArr.sort(keyFunc);

有效。

答案 3 :(得分:0)

您可以在所需函数上使用闭包。

const
    keyFunc = value => Math.abs(value),
    sortBy = fn => (a, b) => fn(a) - fn(b),
    array = [1, 3, -2];

array.sort(sortBy(keyFunc));
console.log(array); // [1, -2, 3]