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'}]);
nhaa123
fonte

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']);
djskinner
fonte
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 [email protected]. 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();
RomanMinkin
fonte
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
Sugira uma resposta? stackoverflow.com/questions/62611489/…
reacg garav 27/06
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

choco
fonte
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
Sugira uma resposta? stackoverflow.com/questions/62611489/…
reacg garav 27/06
13

Campo profundo e campo múltiplo e ordem de direção diferente Lodash> 4

var sortedArray = _.orderBy(mixedArray,
                            ['foo','foo.bar','bar.foo.bar'],               
                            ['desc','asc','desc']);
Mesut Yiğit
fonte
Na verdade, essa seria a resposta agora. sortBy não fornece orientação, mas orderBy fornece.
Pablo Palacios
Sugira uma resposta? stackoverflow.com/questions/62611489/…
reacg garav 27/06
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
         || …;
 });
Bergi
fonte
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'])

Alejandro Silva
fonte
Eu acho que você queria usar _.sortByOrder?
10246 AJ
não é possível encontrar a variável _
Vishal Vaghasiya
Sugira uma resposta? stackoverflow.com/questions/62611489/…
reacg garav 27/06
0

Você também pode tentar isso:

var data= _.reverse(_.sortBy(res.locals.subscriptionList.items, ['type', 'name']));
Shubham Verma
fonte
Isso vai ser muito mais lento do que usar _.orderBy
reggaeguitar 5/05