Żadna z tych odpowiedzi nie jest idealna jako metoda ogólnego przeznaczenia do korzystania z wielu pól w sortowaniu. Wszystkie powyższe podejścia są nieefektywne, ponieważ wymagają wielokrotnego sortowania tablicy (co na wystarczająco dużej liście może spowolnić działanie) lub generują ogromne ilości śmieci, które maszyna wirtualna będzie musiała wyczyścić (i ostatecznie spowolnić program wyłączony).
Oto rozwiązanie, które jest szybkie, wydajne, łatwo umożliwia odwrotne sortowanie i może być używane z underscore
lub lodash
lub bezpośrednio zArray.sort
Najważniejszą częścią jest compositeComparator
metoda, która przyjmuje tablicę funkcji komparatora i zwraca nową funkcję komparatora złożonego.
/**
* Chains a comparator function to another comparator
* and returns the result of the first comparator, unless
* the first comparator returns 0, in which case the
* result of the second comparator is used.
*/
function makeChainedComparator(first, next) {
return function(a, b) {
var result = first(a, b);
if (result !== 0) return result;
return next(a, b);
}
}
/**
* Given an array of comparators, returns a new comparator with
* descending priority such that
* the next comparator will only be used if the precending on returned
* 0 (ie, found the two objects to be equal)
*
* Allows multiple sorts to be used simply. For example,
* sort by column a, then sort by column b, then sort by column c
*/
function compositeComparator(comparators) {
return comparators.reduceRight(function(memo, comparator) {
return makeChainedComparator(comparator, memo);
});
}
Będziesz także potrzebować funkcji komparatora do porównywania pól, według których chcesz sortować. naturalSort
Funkcja stworzy komparator podana konkretna dziedzina. Napisanie komparatora do sortowania wstecznego jest również trywialne.
function naturalSort(field) {
return function(a, b) {
var c1 = a[field];
var c2 = b[field];
if (c1 > c2) return 1;
if (c1 < c2) return -1;
return 0;
}
}
(Cały dotychczasowy kod jest wielokrotnego użytku i może być przechowywany na przykład w module narzędziowym)
Następnie musisz utworzyć komparator złożony. W naszym przykładzie wyglądałoby to tak:
var cmp = compositeComparator([naturalSort('roomNumber'), naturalSort('name')]);
Spowoduje to posortowanie według numeru pokoju, po którym następuje nazwa. Dodanie dodatkowych kryteriów sortowania jest trywialne i nie wpływa na wydajność sortowania.
var patients = [
{name: 'John', roomNumber: 3, bedNumber: 1},
{name: 'Omar', roomNumber: 2, bedNumber: 1},
{name: 'Lisa', roomNumber: 2, bedNumber: 2},
{name: 'Chris', roomNumber: 1, bedNumber: 1},
];
// Sort using the composite
patients.sort(cmp);
console.log(patients);
Zwraca następujące dane
[ { name: 'Chris', roomNumber: 1, bedNumber: 1 },
{ name: 'Lisa', roomNumber: 2, bedNumber: 2 },
{ name: 'Omar', roomNumber: 2, bedNumber: 1 },
{ name: 'John', roomNumber: 3, bedNumber: 1 } ]
Powodem, dla którego wolę tę metodę jest to, że pozwala ona na szybkie sortowanie na dowolnej liczbie pól, nie generuje dużo śmieci ani nie wykonuje konkatenacji ciągów wewnątrz sortowania i może być łatwo używana, aby niektóre kolumny były sortowane odwrotnie, podczas gdy kolumny kolejności używają naturalnych sortować.