Como classificar uma matriz de hashes em ruby


147

Eu tenho uma matriz, cada um de cujos elementos é um hash com três pares de chave / valor:

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

Eu gostaria de classificar os dados zippara que todos os phones na mesma área estejam juntos. Ruby tem uma maneira fácil de fazer isso? Pode will_paginatepaginar dados em uma matriz?


Se você estiver gerando a matriz, em vez de ser um dado, considere torná-la um hash, com elementos (por exemplo) [city,zip]=>phoneou city=>{zip1=>[<phones>], zip2=>...}.
Cary Swoveland

Respostas:


364

Simples:

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

Nota:

Ao usar, sort_byé necessário atribuir o resultado a uma nova variável: array_of_hashes = array_of_hashes.sort_by{}caso contrário, você pode usar o método "bang" para modificar no local:array_of_hashes.sort_by!{}


8
Ao usar, sort_byé necessário atribuir o resultado a uma nova variável: array_of_hashes = array_of_hashes.sort_by{}caso contrário, você pode usar o método "bang" para modificar no local:array_of_hashes.sort_by!{}
Andrew

11
Ainda mais curto:array_of_hashes.sort_by(&:zip)
Etienne

24
@ Etienne: Esse é um atalho para .sort_by { |hsh| hsh.zip }e, portanto, só funcionará se .zipfor definido como um método em cada Hash. Por padrão, os hashes não expõem suas chaves como métodos, então acho que você provavelmente tem algo mais acontecendo lá.
Gareth

Observe o estrondo:array_of_hashes.sort_by!(&:zip)
Diego D

@ Gareth: No caso de ActiveRecords, .zipe [:zip]ambos funcionarão. Os ActiveRecords têm ambos os estilos definidos.
Atul Vaibhav 27/06

17
sorted = dataarray.sort {|a,b| a[:zip] <=> b[:zip]}

10

Use o bang para modificar no local a matriz:

array_of_hashes.sort_by!(&:zip)

Ou redesigne-o:

array_of_hashes = array_of_hashes.sort_by(&:zip)

Observe que o método sort_by classifica por ordem crescente.

Se você precisar classificar em ordem decrescente, poderá fazer algo assim:

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

ou

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

6
A notação &:é um atalho para method, não attribute! Você está presumindo que o Hash tem métodos que refletem atributos ..
Andre Figueiredo

1
Obrigado pelo reversemétodo: p
Alain ANDRE 2/17

4

Se você quiser paginar os dados na matriz, deverá exigir 'will_paginate / array' em seu controlador


2

Se você possui Hash aninhado (Hash dentro de um formato de hash) como elementos de matriz (uma estrutura como a seguinte) e deseja classificá-lo por chave (data aqui)

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

Use o método Array 'sort_by' como

data.sort_by { |element| element.keys.first }
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.