Поддерживает ли JS сортировку с помощью ключевой функции, а не компаратора? - PullRequest
0 голосов
/ 07 октября 2018

JavaScript array.sort метод принимает в качестве аргумента необязательную функцию сравнения, которая принимает два аргумента и решает, какой из них меньше другого.

Однако иногда это может бытьудобнее настроить порядок сортировки с помощью ключевой функции , которая принимает функцию one в качестве аргумента и присваивает ей ключ сортировки .Например:

function keyFunc(value){
    return Math.abs(value);
}

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

Есть ли в JavaScript поддержка этого или нет возможности написать полноценную функцию сравнения?

Ответы [ 4 ]

0 голосов
/ 07 октября 2018

Как уже говорилось, вы должны написать эту функциональность самостоятельно или расширить текущий массив 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>
0 голосов
/ 07 октября 2018

Вы можете легко вычесть "ключи" из двух элементов:

 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);

работает.

0 голосов
/ 07 октября 2018

Вы можете использовать замыкание над требуемой функцией.

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]
0 голосов
/ 07 октября 2018

Нет поддержки для точно того, что вы описываете, но довольно просто написать стандартную функцию .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]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...