Clasificación de múltiples columnas lodash

151

Hay un método ingenioso para ordenar una matriz de objetos en función de varias propiedades:

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

Sin embargo, eso es solo para la clasificación ascendente. ¿Hay alguna forma práctica de definir la dirección por columna? P.ej

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

Respuestas:

330

A partir de lodash 3.5.0 puede usar sortByOrder (renombrado orderBy en v4.3.0):

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

Desde la versión 3.10.0 incluso puede usar la semántica estándar para ordenar (asc, desc):

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

En la versión 4 de lodash, este método ha sido renombrado como orderBy :

var data = _.orderBy(array_of_objects, ['type','name'], ['asc', 'desc']);
djskinner
fuente
77
Para su información, esta función ha cambiado de nombre a _.orderBy ( lodash.com/docs#orderBy ) en Lodash a partir de 4.3.0. La función de ordenación normal se llama _.sortBy ( lodash.com/docs#sortBy )
Nidhin David
2
Estoy obteniendo la _.sortByOrder is not a functionúltima versión de lodash.
Chovy
66
¿Por qué lodash mantiene las funciones de cambio de nombre?
Kenny Worden
13
La , ['asc', 'desc']parte simplemente me está ignorando con [email protected]. Todo está ordenado de forma ascendente.
maninak
44
@maninak Esto es para _.sortBy. Intenta en su _.orderBylugar. Espero que esto ayude.
pcasme
45

Siempre puedes usar Array.prototype.reverse()

var data = _.sortBy(array_of_objects, ['type', 'name']).reverse();
RomanMinkin
fuente
ja eso es inteligente. para un orden numérico ascendente (lodash predeterminado descendente) utilicé esto: _.sortBy (array_of_objects, "some_numerical_value_key"). reverse ()
devonj
3
Si bien es lo suficientemente bueno para algunos casos, el efecto de esto es ordenar descender en AMBAS columnas, que no es lo que la pregunta plantea.
Inkling
¿Sugerir una respuesta? stackoverflow.com/questions/62611489/…
reacg garav
14

Vale la pena señalar que si desea ordenar propiedades particulares descendentes, no desea simplemente agregar .reverse () al final, ya que esto hará que todos los tipos desciendan.

Para hacer que las clases particulares desciendan, encadene sus clases de menos significativo a más significativo, llamando a .reverse () después de cada tipo que desee que descienda.

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

Dado que la ordenación _ es una ordenación estable, puede encadenar e invertir de manera segura porque si dos elementos tienen el mismo valor para una propiedad, se conserva su orden.

Más información

calamar
fuente
Si no tienes suficiente representante para comentar, no lo hagas. Aunque ha desarrollado esto en una respuesta real, lo cual es bueno, pero ni siquiera necesita mencionar ese hecho.
ArtOfCode
¿Sugerir una respuesta? stackoverflow.com/questions/62611489/…
reacg garav
13

Ordenes de campo profundo y campo múltiple y dirección diferente Lodash> 4

var sortedArray = _.orderBy(mixedArray,
                            ['foo','foo.bar','bar.foo.bar'],               
                            ['desc','asc','desc']);
Mesut Yiğit
fuente
En realidad, esta sería la respuesta ahora. sortBy no te da instrucciones, pero orderBy sí.
Pablo Palacios
¿Sugerir una respuesta? stackoverflow.com/questions/62611489/…
reacg garav
5

¿Hay alguna forma práctica de definir la dirección por columna?

No. No puede especificar el orden de clasificación que no sea mediante una función de devolución de llamada que invierte el valor. Ni siquiera esto es posible para una clasificación de varias columnas.

Tal vez puedas hacer

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

Para todo lo demás, deberá recurrir al nativo .sort()con una función de comparación personalizada:

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

En la documentación de la versión 4.11.x, dice: `" Este método es como _.sortBy, excepto que permite especificar el orden de los iterados para ordenar. Si los pedidos no se especifican, todos los valores se ordenan en orden ascendente. De lo contrario , especifique un orden de "desc" para descendente o "asc" para el orden de clasificación ascendente de los valores correspondientes ". (fuente https://lodash.com/docs/4.17.10#orderBy )

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

Alejandro Silva
fuente
Creo que querías usar _.sortByOrder?
AJ Richardson
no puede encontrar la variable _
Vishal Vaghasiya
¿Sugerir una respuesta? stackoverflow.com/questions/62611489/…
reacg garav
0

También puedes probar esto:

var data= _.reverse(_.sortBy(res.locals.subscriptionList.items, ['type', 'name']));
Shubham Verma
fuente
Esto va a ser mucho más lento que usar _.orderBy
reggaeguitar