Cara mengurutkan array hash di ruby

148

Saya memiliki sebuah array, yang masing-masing elemennya adalah hash dengan tiga pasangan kunci / nilai:

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

Saya ingin menyortir data zipsehingga semua yang ada phonedi area yang sama sama. Apakah Ruby punya cara mudah untuk melakukan itu? Bisakah will_paginatepaginasi data dalam array?

jpw
sumber
Jika Anda membuat array, alih-alih diberikan, pertimbangkan membuatnya sebagai hash, dengan elemen (misalnya) [city,zip]=>phoneatau city=>{zip1=>[<phones>], zip2=>...}.
Cary Swoveland

Jawaban:

365

Sederhana:

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

catatan:

Saat menggunakan, sort_byAnda perlu menetapkan hasilnya ke variabel baru: array_of_hashes = array_of_hashes.sort_by{}jika tidak, Anda dapat menggunakan metode "bang" untuk memodifikasi:array_of_hashes.sort_by!{}

Gareth
sumber
8
Saat menggunakan sort_byAnda perlu menetapkan hasilnya ke variabel baru: array_of_hashes = array_of_hashes.sort_by{}jika tidak, Anda dapat menggunakan metode "bang" untuk memodifikasi di tempat:array_of_hashes.sort_by!{}
Andrew
11
Bahkan lebih pendek:array_of_hashes.sort_by(&:zip)
Etienne
24
@Titienne: Itu adalah jalan pintas .sort_by { |hsh| hsh.zip }dan karenanya hanya akan berfungsi jika .zipdidefinisikan sebagai metode pada setiap Hash. Secara default hash tidak mengekspos kunci mereka sebagai metode, jadi saya kira Anda mungkin punya sesuatu yang terjadi di sana.
Gareth
Catat bang:array_of_hashes.sort_by!(&:zip)
Diego D
@ Gareth: Dalam hal ActiveRecords, .zipdan [:zip]keduanya akan berfungsi. ActiveRecords memiliki kedua gaya yang ditentukan.
Atul Vaibhav
17
sorted = dataarray.sort {|a,b| a[:zip] <=> b[:zip]}
Edu
sumber
10

Gunakan bang untuk memodifikasi di tempat array:

array_of_hashes.sort_by!(&:zip)

Atau tetapkan kembali:

array_of_hashes = array_of_hashes.sort_by(&:zip)

Perhatikan bahwa metode sort_by akan mengurutkan berdasarkan urutan naik.

Jika Anda perlu menyortir dengan urutan menurun, Anda dapat melakukan sesuatu seperti ini:

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

atau

array_of_hashes = array_of_hashes.sort_by(&:zip).reverse
Diego D
sumber
6
Notasi &:adalah jalan pintas method, bukan attribute! Anda menganggap bahwa Hash memiliki metode yang mencerminkan atribut ..
Andre Figueiredo
1
Terima kasih untuk reversemetodenya: p
Alain ANDRE
4

Jika Anda ingin memberi paginasi data dalam array, Anda harus meminta 'will_paginate / array' di controller Anda

taivn07
sumber
2

Jika Anda memiliki Nested Hash (Hash di dalam format hash) sebagai elemen Array (struktur seperti berikut) dan ingin mengurutkannya dengan kunci (tanggal di sini)

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

Gunakan metode Array 'sort_by' sebagai

data.sort_by { |element| element.keys.first }
Abhi
sumber