Javascript sort пользовательская функция сравнения - сортировка отсортированного массива - PullRequest
21 голосов
/ 23 августа 2011

У меня есть массив объектов следующей формы:

arr[0] = { 'item1' : 1234, 'item2' : 'a string' };

Сначала я сортирую по 'item1', что довольно просто. Теперь я хочу снова отсортировать arr (что отсортировано по 'item1'), но на этот раз по 'item2', но только для элементов, где 'item1' одинаково. Конечный массив будет выглядеть так:

* * 1010

Я пытался написать функцию сортировки для второго случая следующим образом:

arr.sort(function(a,b){
  if(a.item1 === b.item1){
    return a.item2 > b.item2 ? 1 : a.item2 < b.item2 : -1 : 0;
  }
});

Я мог бы объединить две сортировки в одну функцию, чтобы получить окончательный отсортированный массив, но в некоторых случаях мне придется сортировать по 'item1' или 'item2'.

Ответы [ 3 ]

28 голосов
/ 23 августа 2011

Вы можете иметь четыре различные функции сравнения - одну сортировку по номеру 1, одну по элементу 2, одну по элементу 1, затем item2, и одну по item2, затем item1.

Например:

arr.sort(function(a,b){
  if(a.item1 == b.item1){
    return a.item2 > b.item2 ? 1 : a.item2 < b.item2 ? -1 : 0;
  }

  return a.item1 > b.item1 ? 1 : -1;
});
0 голосов
/ 30 мая 2019

Я использую этот помощник в TypeScript:

// Source
type ComparatorSelector<T> = (value: T, other: T) => number | string | null;

export function createComparator<T>(...selectors: ComparatorSelector<T>[]) {
  return (a: T, b: T) => {
    for (const selector of selectors) {
      const valA = selector(a, b);
      if (valA === null) continue;
      const valB = selector(b, a);
      if (valB === null || valA == valB) continue;
      if (valA > valB) return 1;
      if (valA < valB) return -1;
    }
    return 0;
  };
}

// Usage:
const candidates: any[] = [];
// ...
candidates.sort(createComparator(
  (x) => x.ambiguous,
  (_, y) => y.refCount, // DESC
  (x) => x.name.length,
  (x) => x.name,
));
0 голосов
/ 13 апреля 2018

Или как простой oneliner для сортировки по первому и второму приоритетам, вы можете расширить его по своему желанию, просто заменив 0 на другую цепочку сравнения.Переключите <</strong> и > или -1 и 1 для обратного порядка.

someArray.sort(function(a,b) {
  return a.item1 > b.item1 ? 1 : a.item1 < b.item1 ? -1 : a.item2 > b.item2 ? 1 : a.item2 < b.item2 ? -1 : 0;
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...