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

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

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 lodash@4.17.10. 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();

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


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


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



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
         || …;
 });

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'])


Creo que querías usar _.sortByOrder?
AJ Richardson

no puede encontrar la variable _
Vishal Vaghasiya


0

También puedes probar esto:

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

Esto va a ser mucho más lento que usar _.orderBy
reggaeguitar
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.