for - ruby select
Ordenación: ordenación de matriz basada en múltiples condiciones en Ruby (3)
Tengo una matriz multidimensional como tal:
[
[name, age, date, gender]
[name, age, date, gender]
[..]
]
Me pregunto cuál es la mejor manera de ordenar esta matriz en función de múltiples condiciones ... Por ejemplo, ¿cómo clasificaría la edad por nombre y luego por nombre?
Estaba jugando con el método de sort
manera:
array.sort { |a,b| [ a[1], a[0] ] <=> [ b[1], b[0] ] }
Además de que realmente no entiendo esta sintaxis, no estoy obteniendo los resultados que esperaría. ¿Debo usar el método de sort
? ¿Debo estar comparando los resultados individualmente al mapping
la matriz?
Esto debería funcionar:
array.sort { |a,b| [ a[1], a[0] ] <=> [ b[1], b[0] ] }
Entonces que hace esto? Utiliza muchos idiomas de Ruby.
- Primero están los bloques, que son una especie de devoluciones de llamada o funciones / clases anónimas en otros idiomas. El método de
sort
de Array los utiliza para comparar dos elementos según el valor de retorno del bloque. Puedes leer todo sobre ellos here . - El siguiente es el operador
<=>
. Devuelve -1 si el primer argumento es menor que el segundo, 0 si son iguales y 1 si el primero es mayor que el segundo. Cuando lo uses con arrays, comparará los arrays de manera elemental hasta que uno de ellos devuelva -1 o 1. Si los arrays son iguales, obtendrás 0.
Según entiendo, primero debe ordenar por edad, y luego, si más de un registro tiene la misma edad, ordene ese subconjunto por nombre.
Esto funciona para mi
people = [
["bob", 15, "male"],
["alice", 25, "female"],
["bob", 56, "male"],
["dave", 45, "male"],
["alice", 56, "female"],
["adam", 15, "male"]
]
people.sort{|a,b| (a[1] <=> b[1]) == 0 ? (a[0] <=> b[0]) : (a[1] <=> b[1]) }
# The sorted array is
[["adam", 15, "male"],
["bob", 15, "male"],
["alice", 25, "female"],
["dave", 45, "male"],
["alice", 56, "female"],
["bob", 56, "male"]]
Lo que está haciendo es comparar primero por edad, y si la edad es la misma (<=> vuelve a 0) comparando el nombre.
Siempre debe usar sort_by
para una clasificación con clave. No solo es mucho más legible, sino que también es mucho más eficiente. Además, también preferiría usar el enlace de desestructuración, de nuevo, para facilitar la lectura:
ary.sort_by {|name, age| [age, name] }