A partir de esta pregunta original , ¿cómo aplicaría una ordenación en varios campos?
Usando esta estructura ligeramente adaptada, ¿cómo ordenaría la ciudad (ascendente) y luego el precio (descendente)?
var homes = [
{"h_id":"3",
"city":"Dallas",
"state":"TX",
"zip":"75201",
"price":"162500"},
{"h_id":"4",
"city":"Bevery Hills",
"state":"CA",
"zip":"90210",
"price":"319250"},
{"h_id":"6",
"city":"Dallas",
"state":"TX",
"zip":"75000",
"price":"556699"},
{"h_id":"5",
"city":"New York",
"state":"NY",
"zip":"00010",
"price":"962500"}
];
Me gustó el hecho de que se dio una respuesta que proporcionó un enfoque general. Cuando planeo usar este código, tendré que ordenar las fechas y otras cosas. La capacidad de "cebar" el objeto parecía práctica, si no un poco engorrosa.
Intenté construir esta respuesta en un buen ejemplo genérico, pero no tengo mucha suerte.
javascript
arrays
sorting
Miguel
fuente
fuente
sort(["first-field", "ASC"], ["second-field", "DSC"]);
esto se complica aún más cuando trato de agregar la lógica de "primer" de la primera respuesta para que pueda manejar las fechas, la insensibilidad a mayúsculas y minúsculas, etc.Respuestas:
Un método de clasificación multidimensional, basado en esta respuesta :
Actualización : Aquí hay una versión "optimizada". Hace mucho más preprocesamiento y crea una función de comparación para cada opción de clasificación de antemano. Es posible que necesite más memoria (ya que almacena una función para cada opción de clasificación, pero debería funcionar un poco mejor, ya que no tiene que determinar la configuración correcta durante la comparación. Sin embargo, no he hecho ningún perfil.
Ejemplo de uso:
MANIFESTACIÓN
Función original:
MANIFESTACIÓN
fuente
para una solución no genérica y simple a su problema exacto:
fuente
if
declaración no tiene sentido.a.localeCompare(b)
en la última línea de la cadena de comparar ... ver los documentosif (a.city === b.city)
? Es decir, si las dos ciudades son iguales, compare los precios, de lo contrario compare las ciudades.Podría usar un enfoque de clasificación encadenada tomando el delta de valores hasta que alcance un valor no igual a cero.
O, usando es6, simplemente:
fuente
Aquí hay un enfoque funcional simple. Especifique el orden de clasificación utilizando la matriz. Anteponer menos para especificar el orden descendente.
Editar: en ES6 es aún más corto!
fuente
[10,100,11,9]
. ¿Me he perdido algo?Hoy hice un clasificador multifuncional bastante genérico. Puede echar un vistazo a thenBy.js aquí: https://github.com/Teun/thenBy.js
Le permite usar el Array.sort estándar, pero con el estilo firstBy (). ThenBy (). ThenBy (). Es mucho menos código y complejidad que las soluciones publicadas anteriormente.
fuente
La siguiente función le permitirá ordenar una matriz de objetos en una o varias propiedades, ya sea ascendente (predeterminado) o descendente en cada propiedad, y le permitirá elegir si desea o no realizar comparaciones entre mayúsculas y minúsculas. De manera predeterminada, esta función realiza tipos sin distinción entre mayúsculas y minúsculas.
El primer argumento debe ser la matriz que contiene los objetos. Los argumentos posteriores deben ser una lista de cadenas separadas por comas que hacen referencia a las diferentes propiedades de objeto para ordenar. El último argumento (que es opcional) es un valor booleano para elegir si se realizan o no las mayúsculas y minúsculas. Úselo
true
para las mayúsculas y minúsculas.La función ordenará cada propiedad / clave en orden ascendente de forma predeterminada. Si quieres una clave particular para ordenar en orden descendente, entonces en vez pasar de una matriz en este formato:
['property_name', true]
.Aquí hay algunos ejemplos de usos de la función seguidos de una explicación (donde
homes
hay una matriz que contiene los objetos):objSort(homes, 'city')
-> ordenar por ciudad (ascendente, sensible a mayúsculas y minúsculas)objSort(homes, ['city', true])
-> ordenar por ciudad (descendente, sensible a mayúsculas y minúsculas)objSort(homes, 'city', true)
-> ordenar por ciudad y luego precio (ascendente, mayúsculas y minúsculas )objSort(homes, 'city', 'price')
-> ordenar por ciudad y luego precio (ambos ascendentes, mayúsculas y minúsculas)objSort(homes, 'city', ['price', true])
-> ordenar por ciudad (ascendente) luego precio (descendente), mayúsculas y minúsculas)Y sin más preámbulos, aquí está la función:
Y aquí hay algunos datos de muestra:
fuente
Este es un truco completo, pero creo que agrega valor a esta pregunta porque es básicamente una función de biblioteca enlatada que puede usar de forma inmediata.
Si su código tiene acceso
lodash
o una biblioteca compatible con lodash,underscore
entonces puede usar el_.sortBy
método. El fragmento a continuación se copia directamente de la documentación lodash .Parece que los resultados comentados en los ejemplos devuelven matrices de matrices, pero eso solo muestra el orden y no los resultados reales, que son una matriz de objetos.
fuente
Aquí hay otro que quizás esté más cerca de su idea para la sintaxis
Demostración: http://jsfiddle.net/Nq4dk/2/
Editar: solo por diversión, aquí hay una variación que solo toma una cadena tipo sql, para que pueda hacer
sortObjects(homes, "city, price desc")
fuente
Uno más simple:
fuente
Me gusta el enfoque de SnowBurnt, pero necesita un ajuste para probar la equivalencia en la ciudad, NO una diferencia.
fuente
Aquí hay una clasificación genérica multidimensional, que permite la inversión y / o mapeo en cada nivel.
Escrito en mecanografiado. Para Javascript, mira este JSFiddle
El código
Ejemplos de uso
Ordenar una matriz de personas por apellido, luego nombre:
Ordene los códigos de idioma por su nombre , no por su código de idioma (ver
map
), luego por versión descendente (verreverse
).fuente
Una forma dinámica de hacerlo con MÚLTIPLES teclas:
Utilizar:
fuente
Aquí hay una versión genérica de la solución @ Snowburnt:
Esto se basa en una rutina de clasificación que estoy usando. No probé este código específico, por lo que puede tener errores, pero se entiende la idea. La idea es ordenar según el primer campo que indica una diferencia y luego parar e ir al siguiente registro. Por lo tanto, si está ordenando por tres campos y el primer campo en la comparación es suficiente para determinar el orden de clasificación de los dos registros que se están ordenando, devuelva ese resultado de clasificación y pase al siguiente registro.
Lo probé (en realidad con una lógica de clasificación un poco más compleja) en 5000 registros y lo hizo en un abrir y cerrar de ojos. Si realmente está cargando más de 1000 registros al cliente, probablemente debería estar usando la clasificación y el filtrado del lado del servidor.
Este código no maneja la distinción entre mayúsculas y minúsculas, pero se lo dejo al lector para manejar esta modificación trivial.
fuente
Aquí está mi solución basada en el idioma de transformación de Schwartz , espero que lo encuentre útil.
Aquí hay un ejemplo de cómo usarlo:
fuente
De otra manera
fuente
Cómo usar (poner - (menos) signo antes del campo si desea ordenar en orden descendente campo particular)
Usando la función anterior, puede ordenar cualquier matriz json con múltiples campos. No es necesario cambiar el cuerpo de la función.
fuente
Adaptación de la respuesta de @chriskelly.
La mayoría de las respuestas pasan por alto que el precio no se ordenará correctamente si el valor está entre los diez mil y menos o más de un millón. La razón de ser JS se ordena alfabéticamente. Se respondió bastante bien aquí, ¿Por qué JavaScript no puede ordenar "5, 10, 1" y aquí? Cómo ordenar una matriz de enteros correctamente .
En última instancia, tenemos que hacer una evaluación si el campo o nodo por el que estamos clasificando es un número. No estoy diciendo que usar
parseInt()
en este caso sea la respuesta correcta, los resultados ordenados son más importantes.Un violín para probar con
fuente
price
en el ejemplo está en formato de cadena. Si desea que funcione correctamente con mi ejemplo, use map para convertir el campo que desea numerar primero. es decirconst correctedHomes = homes.map(h => ({...h, price: +h.price}))
Wow, hay algunas soluciones complejas aquí. Tan complejo que decidí idear algo más simple pero también bastante poderoso. Aquí está;
Y aquí hay un ejemplo de cómo lo usas.
Primero se ordenará por la precedencia de los atributos, luego por el valor de los atributos.
fuente
Aquí hay una forma extensible de ordenar por múltiples campos.
Notas
a.localeCompare(b)
está universalmente compatible y vuelve -1,0,1 sia<b
,a==b
,a>b
respectivamente.||
en la última línea dacity
prioridad sobreprice
.-price_order
var date_order = new Date(left.date) - new Date(right.date);
funciona como numéricos, porque la fecha de matemáticas se convierte en milisegundos desde el año 1970.return city_order || -price_order || date_order;
fuente
Creo que esta puede ser la forma más fácil de hacerlo.
https://coderwall.com/p/ebqhca/javascript-sort-by-two-fields
Es realmente simple y lo probé con 3 pares de valores clave diferentes y funcionó muy bien.
Aquí hay un ejemplo simple, mira el enlace para más detalles
fuente
Aquí está el mío para su referencia, con ejemplo:
fuente
Estaba buscando algo similar y terminé con esto:
Primero tenemos una o más funciones de clasificación, siempre devolviendo 0, 1 o -1:
Puede crear más funciones para cada propiedad que desee ordenar.
Luego tengo una función que combina estas funciones de clasificación en una:
Esto se puede usar para combinar las funciones de clasificación anteriores de una manera legible:
Cuando una función de clasificación devuelve 0, se llamará a la siguiente función de clasificación para una clasificación adicional.
fuente
Solo otra opción. Considere usar la siguiente función de utilidad:
Ejemplo de uso (en su caso):
Cabe señalar que esta función se puede generalizar aún más para poder usar propiedades anidadas como 'address.city' o 'style.size.width', etc.
fuente
Este es un algoritmo recursivo para ordenar por múltiples campos mientras tiene la oportunidad de formatear valores antes de la comparación.
Si ayb son iguales, solo intentará el siguiente campo hasta que no haya ninguno disponible.
fuente
fuente
Aquí 'AffiliateDueDate' y 'Title' son columnas, ambas están ordenadas en orden ascendente.
fuente
Ordenar en dos campos de fecha y un ejemplo de campo numérico:
http://jsfiddle.net/hcWgf/57/
fuente
Utilizando :
Mostrar fragmento de código
fuente
¿Qué tal esta solución simple:
Basado en esta pregunta javascript sort array by multiple (number) fields
fuente