2014-04-08 17 views
76

Jest fajny sposób aby posortować tablicę obiektów na podstawie kilku właściwości:lodash multi-kolumna SortBy malejąco

var data = _.sortBy(array_of_objects, ['type', 'name']);

jednak, że jest tylko dla rosnącej sortowania. Czy jest jakiś przydatny sposób definiowania kierunku na kolumnę? Na przykład.

var data = _.sortBy(array_of_objects, [{'type': 'asc'}, {'name': 'desc'}]);

Odpowiedz

164

Od lodash 3.5.0 można wykorzystać sortByOrder (przemianowany orderBy w wersji 4.3.0):

var data = _.sortByOrder(array_of_objects, ['type','name'], [true, false]); 

Od wersja 3.10.0 można nawet użyć standardowych semantykę do zamówienia (asc, desc):

var data = _.sortByOrder(array_of_objects, ['type','name'], ['asc', 'desc']); 

W wersja 4 z lodash metoda ta została zmieniona orderBy:

var data = _.orderBy(array_of_objects, ['type','name'], ['asc', 'desc']); 
+6

Dla twojej informacji, ta funkcja została przemianowana na _.orderBy (https://lodash.com/docs#orderBy) w Lodash od wersji 4.3.0. Funkcja sortowania normalnego nazywa się _sortBy (https://lodash.com/docs#sortBy) –

+1

Otrzymuję '_.sortByOrder nie jest funkcją' w najnowszej wersji aplikacji lodash. – chovy

+0

Zakładając, że używasz Lodash 4, 'sortByOrder' już nie istnieje. Obecnie nosi on nazwę 'orderBy' – djskinner

5

Czy jest jakiś sposób przydatny kierunek definiowania na kolumnę?

Nie Możesz podać kolejność sortowania inną niż przez funkcję zwrotną, która odwraca wartość. Nawet nie jest to możliwe w przypadku sortowania wielokolumnowego.

Możesz być w stanie zrobić

_.each(array_of_objects, function(o) { 
    o.typeDesc = -o.type; // assuming a number 
}); 
_.sortBy(array_of_objects, ['typeDesc', 'name']) 

Na wszystko inne, trzeba będzie uciekać się do rodzimej .sort() z funkcją porównania niestandardowe:

array_of_objects.sort(function(a, b) { 
    return a.type - b.type // asc 
     || +(b.name>a.name)||-(a.name>b.name) // desc 
     || …; 
}); 
32

zawsze można użyć Array.prototype.reverse()

var data = _.sortBy(array_of_objects, ['type', 'name']).reverse(); 
+0

ha to sprytnie sortowanie numeryczne rosnąco (domyślne wartości domyślne) Użyłem tego: _sortBy (array_of_objects, "some_numerical_value_key"). reverse() – devonJS

+8

yep, jest to możliwe, ale nie jest tak dobre pod względem wydajności ... – BotanMan

+1

Chociaż dobre wystarczające dla niektórych przypadków, efektem tego jest posortowanie malejącej kolumny BOTH, co nie jest tym, o co pyta. – Inkling

9

Warto zauważyć, że jeśli chcesz posortować szczególne właściwości malejące, nie chcesz po prostu dodawać .reverse() na końcu, ponieważ spowoduje to zejście wszystkich rodzajów.

Aby uprościć poszczególne sortowania, połącz swoje sortowanie od najmniej znaczącego do najbardziej znaczącego, wywołując metodę .reverse() po każdym sortowaniu, które chcesz zstępować.

var data = _(data).chain() 
    .sort("date") 
    .reverse() // sort by date descending 
    .sort("name") // sort by name ascending 
    .result() 

Od _ jest rodzaj sortowania jest stabilna, można bezpiecznie łańcucha i odwrócić rodzaju bo jeśli dwa elementy mają taką samą wartość dla nieruchomości, ich kolejność jest zachowana.

More information

+0

Jeśli nie masz wystarczającej liczby przedstawicieli, aby skomentować, nie komentuj. Mimo że udało ci się to ująć w rzeczywistą odpowiedź, która jest dobra, ale nie musisz nawet wspominać o tym fakcie. – ArtOfCode

1

W dokumentacji wersji 4.11.x, mówi: ` „Ta metoda jest jak _.sortBy oprócz tego, że pozwala określające sortuj zamówienia iteracji, aby sortować według. Jeśli zamówienia nie są określone, wszystkie wartości są sortowane w porządku rosnącym. W przeciwnym razie podaj kolejność "desc" dla malejących lub "asc" dla rosnącej kolejności sortowania odpowiadających wartości." (źródło https://lodash.com/docs#sortBy)

let sorted = _.sortBy(this.items, ['fieldFoo', 'fieldBar'], ['asc', 'desc'])

+0

Myślę, że zamierzałeś użyć '_.sortByOrder'? –

4

Głębokie Pole & wielo pole & inny kierunek zamawiania Lodash> 4

var sortedArray = _.orderBy(mixedArray, 
          ['foo','foo.bar','bar.foo.bar'],    
          ['desc','asc','desc']); 
+0

Właściwie to byłaby teraz odpowiedź. sortBy nie daje ci wskazówek, ale orderBy to robi. – moplin

1

Można też spróbować:

var data= _.reverse(_.sortBy(res.locals.subscriptionList.items, ['type', 'name'])); 
Powiązane problemy