Comment trier un tableau de hachages en ruby

148

J'ai un tableau dont chacun des éléments est un hachage avec trois paires clé / valeur:

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

Je voudrais trier les données par zipafin que tous les phones dans la même zone soient ensemble. Ruby a-t-il un moyen simple de le faire? Peut will_paginatepaginer les données dans un tableau?

jpw
la source
Si vous générez le tableau, plutôt que d'être donné, envisagez d'en faire un hachage à la place, avec des éléments (par exemple) [city,zip]=>phoneou city=>{zip1=>[<phones>], zip2=>...}.
Cary Swoveland

Réponses:

365

Simples:

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

Remarque:

Lors de l'utilisation, sort_byvous devez affecter le résultat à une nouvelle variable: array_of_hashes = array_of_hashes.sort_by{}sinon vous pouvez utiliser la méthode "bang" pour modifier en place:array_of_hashes.sort_by!{}

Gareth
la source
8
Lors de l'utilisation, sort_byvous devez affecter le résultat à une nouvelle variable: array_of_hashes = array_of_hashes.sort_by{}sinon vous pouvez utiliser la méthode "bang" pour modifier sur place:array_of_hashes.sort_by!{}
Andrew
11
Encore plus court:array_of_hashes.sort_by(&:zip)
Etienne
24
@Etienne: C'est un raccourci pour .sort_by { |hsh| hsh.zip }et donc cela ne fonctionnera que si .zipest défini comme une méthode sur chaque Hash. Par défaut, les hachages n'exposent pas leurs clés en tant que méthodes, donc je suppose que vous avez probablement autre chose à faire.
Gareth
Remarquez le coup:array_of_hashes.sort_by!(&:zip)
Diego D
@Gareth: En cas de ActiveRecords, .zipet les [:zip]deux fonctionneront. ActiveRecords a les deux styles définis.
Atul Vaibhav
17
sorted = dataarray.sort {|a,b| a[:zip] <=> b[:zip]}
Edu
la source
10

Utilisez le bang pour modifier en place le tableau:

array_of_hashes.sort_by!(&:zip)

Ou réattribuez-le:

array_of_hashes = array_of_hashes.sort_by(&:zip)

Notez que la méthode sort_by triera par ordre croissant.

Si vous avez besoin de trier par ordre décroissant, vous pouvez faire quelque chose comme ceci:

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

ou

array_of_hashes = array_of_hashes.sort_by(&:zip).reverse
Diego D
la source
6
La notation &:est un raccourci pour method, non attribute! Vous présumez que le Hash a des méthodes reflétant des attributs ..
Andre Figueiredo
1
Merci pour la reverseméthode: p
Alain ANDRE
4

Si vous souhaitez paginer les données dans un tableau, vous devez avoir besoin de 'will_paginate / array' dans votre contrôleur

taivn07
la source
2

Si vous avez un hachage imbriqué (hachage dans un format de hachage) en tant qu'éléments de tableau (une structure comme celle-ci) et que vous souhaitez le trier par clé (date ici)

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

Utilisez la méthode Array 'sort_by' comme

data.sort_by { |element| element.keys.first }
Abhi
la source