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.