ordenação por várias colunas lodash


151

Há um método bacana para classificar uma matriz de objetos com base em várias propriedades:

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

No entanto, isso é apenas para classificação crescente. Existe alguma maneira útil de definir a direção por coluna? Por exemplo

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

Respostas:


329

A partir do lodash 3.5.0, você pode usar sortByOrder (renomeado orderBy na v4.3.0):

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

Desde a versão 3.10.0, você pode usar semântica padrão para pedidos (asc, desc):

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

Na versão 4 do lodash, esse método foi renomeado como orderBy :

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

7
Para informações, essa função foi renomeada para _.orderBy ( lodash.com/docs#orderBy ) no Lodash a partir do 4.3.0. A função de classificação normal é chamado _.sortBy ( lodash.com/docs#sortBy )
Nidhin David

2
Estou entrando _.sortByOrder is not a functionna versão mais recente do lodash.
chovy 04/04

66
Por que o lodash continua renomeando funções?
precisa

13
A , ['asc', 'desc']parte está sendo ignorada por lodash@4.17.10. Tudo é ordenado ascendente.
Maninak

4
@maninak Isto é para _.sortBy. Tente em _.orderByvez disso. Espero que isto ajude.
pcasme

45

Você sempre pode usar Array.prototype.reverse()

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

ha isso é inteligente. para uma classificação crescente numérica (defaults lodash descendente) eu usei esse: _.sortBy (array_of_objects, "some_numerical_value_key") reverse ().
devonj

3
Embora bom o suficiente para alguns casos, o efeito disso é classificar decrescente em AMBAS colunas, que não é o que a pergunta faz.
quer


14

Vale a pena notar que, se você deseja classificar propriedades particulares como descendentes, não deseja simplesmente anexar .reverse () no final, pois isso fará com que todos os tipos descendam.

Para fazer classificações particulares decrescentes, encadeie as classificações menos significativas para as mais significativas, chamando .reverse () após cada classificação que você deseja que seja decrescente.

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

Como a classificação de _ é uma classificação estável, você pode encadear e reverter com segurança, porque se dois itens tiverem o mesmo valor para uma propriedade, sua ordem será preservada.

Mais Informações


Se você não tiver representante suficiente para comentar, não comente. Embora você tenha desenvolvido isso em uma resposta real, o que é bom, mas você nem precisa mencionar esse fato.
ArtOfCode 5/03



5

Existe alguma maneira útil de definir a direção por coluna?

Não. Você não pode especificar a ordem de classificação que não seja por uma função de retorno de chamada que inverta o valor. Nem isso é possível para uma classificação de várias colunas.

Você pode fazer

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

Para todo o resto, você precisará recorrer ao nativo .sort()com uma função de comparação personalizada:

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

3

Na documentação da versão 4.11.x, diz: `" Este método é como _.sortBy, exceto que permite especificar as ordens de classificação dos iterados para classificar. Se as ordens não forem especificadas, todos os valores serão classificados em ordem crescente. Caso contrário, , especifique uma ordem de "desc" para decrescente ou "asc" para ordem de classificação crescente dos valores correspondentes ". (fonte https://lodash.com/docs/4.17.10#orderBy )

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


Eu acho que você queria usar _.sortByOrder?
10246 AJ

não é possível encontrar a variável _
Vishal Vaghasiya


0

Você também pode tentar isso:

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

Isso vai ser muito mais lento do que usar _.orderBy
reggaeguitar 5/05
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.