Cómo ordenar una matriz de hashes en ruby

148

Tengo una matriz, cada uno de cuyos elementos es un hash con tres pares clave / valor:

:phone => "2130001111", :zip => "12345", :city => "sometown"

Me gustaría ordenar los datos zippara que todas las phones de la misma área estén juntas. ¿Ruby tiene una manera fácil de hacer eso? ¿Puede will_paginatepaginar datos en una matriz?

jpw
fuente
Si está generando la matriz, en lugar de ser un hecho, considere convertirla en un hash, con elementos (por ejemplo) [city,zip]=>phoneo city=>{zip1=>[<phones>], zip2=>...}.
Cary Swoveland

Respuestas:

365

Simples:

array_of_hashes.sort_by { |hsh| hsh[:zip] }

Nota:

Cuando lo use sort_by, debe asignar el resultado a una nueva variable: de lo array_of_hashes = array_of_hashes.sort_by{}contrario, puede usar el método "bang" para modificar en su lugar:array_of_hashes.sort_by!{}

Gareth
fuente
8
Cuando lo use sort_by, debe asignar el resultado a una nueva variable: de lo array_of_hashes = array_of_hashes.sort_by{}contrario, puede usar el método "bang" para modificar en su lugar:array_of_hashes.sort_by!{}
Andrew
11
Aún más corto:array_of_hashes.sort_by(&:zip)
Etienne
24
@ Etienne: Ese es un atajo para, .sort_by { |hsh| hsh.zip }por lo que solo funcionará si .zipse define como un método en cada Hash. Por defecto, los hashes no exponen sus claves como métodos, por lo que creo que probablemente hay algo más allí.
Gareth el
Tenga en cuenta la explosión:array_of_hashes.sort_by!(&:zip)
Diego D
@Gareth: en el caso de ActiveRecords, .zipy [:zip]ambos funcionarán. ActiveRecords tiene ambos estilos definidos.
Atul Vaibhav
17
sorted = dataarray.sort {|a,b| a[:zip] <=> b[:zip]}
Edu
fuente
10

Use la explosión para modificar en su lugar la matriz:

array_of_hashes.sort_by!(&:zip)

O reasignarlo:

array_of_hashes = array_of_hashes.sort_by(&:zip)

Tenga en cuenta que el método sort_by se ordenará por orden ascendente.

Si necesita ordenar en orden descendente, puede hacer algo como esto:

array_of_hashes.sort_by!(&:zip).reverse!

o

array_of_hashes = array_of_hashes.sort_by(&:zip).reverse
Diego D
fuente
66
¡La notación &:es un atajo para method, no attribute! Usted presume que el Hash tiene métodos que reflejan atributos ..
Andre Figueiredo
1
Gracias por el reversemétodo: p
Alain ANDRE
4

Si desea paginar los datos en la matriz, debe requerir 'will_paginate / array' en su controlador

taivn07
fuente
2

Si tiene Hash anidado (Hash dentro de un formato hash) como elementos de matriz (una estructura como la siguiente) y desea ordenarlo por clave (fecha aquí)

data =  [
    {
        "2018-11-13": {
            "avg_score": 4,
            "avg_duration": 29.24
        }
    },
    {
         "2017-03-13": {
            "avg_score": 4,
            "avg_duration": 40.24
        }
    },
    {
         "2018-03-13": {
            "avg_score": 4,
            "avg_duration": 39.24
        }
    }
]

Utilice el método Array 'sort_by' como

data.sort_by { |element| element.keys.first }
Abhi
fuente