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?


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!{}


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]}

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

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


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 }
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.