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?


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


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

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

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


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 }
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.