Как отсортировать массив хэшей в ruby

148

У меня есть массив, каждый элемент которого представляет собой хэш с тремя парами ключ / значение:

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

Я хотел бы отсортировать данные, zipчтобы все phoneв одной области были вместе. Есть ли у Ruby простой способ сделать это? Можно ли will_paginateразбивать данные на массивы?

JPW
источник
Если вы генерируете массив, а не как данный, рассмотрите возможность сделать его хешем с элементами (например) [city,zip]=>phoneили city=>{zip1=>[<phones>], zip2=>...}.
Кэри Свовеланд,

Ответы:

365

Simples:

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

Примечание:

При использовании sort_byвам нужно присвоить результат новой переменной: в array_of_hashes = array_of_hashes.sort_by{}противном случае вы можете использовать метод «bang» для изменения на месте:array_of_hashes.sort_by!{}

Gareth
источник
8
При использовании sort_byвам нужно присвоить результат новой переменной: в array_of_hashes = array_of_hashes.sort_by{}противном случае вы можете использовать метод «взрыва» для изменения на месте:array_of_hashes.sort_by!{}
Эндрю
11
Еще короче:array_of_hashes.sort_by(&:zip)
Этьен
24
@Etienne: это ярлык, .sort_by { |hsh| hsh.zip }и он будет работать, только если .zipопределен как метод для каждого хэша. По умолчанию хэши не выставляют свои ключи как методы, поэтому, я думаю, у вас, вероятно, происходит что-то еще.
Гарет
Обратите внимание на взрыв:array_of_hashes.sort_by!(&:zip)
Диего Д
@Gareth: в случае ActiveRecords .zipи то и [:zip]другое будет работать. В ActiveRecords определены оба стиля.
Атул Вайбхав
17
sorted = dataarray.sort {|a,b| a[:zip] <=> b[:zip]}
образование
источник
10

Используйте удар, чтобы изменить массив:

array_of_hashes.sort_by!(&:zip)

Или переназначить его:

array_of_hashes = array_of_hashes.sort_by(&:zip)

Обратите внимание, что метод sort_by будет сортировать по возрастанию.

Если вам нужно отсортировать по убыванию, вы можете сделать что-то вроде этого:

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

или

array_of_hashes = array_of_hashes.sort_by(&:zip).reverse
Диего Д
источник
6
Обозначение &:является сокращением для method, не attribute! Вы предполагаете, что в Hash есть методы, отражающие атрибуты ...
Andre Figueiredo
1
Спасибо за reverseметод: р
Ален
4

Если вы хотите разбить данные на массивы на страницы, вам потребуется 'will_paginate / array' в вашем контроллере

taivn07
источник
2

Если у вас есть Nested Hash (Hash внутри хеш-формата) в качестве элементов Array (структура, подобная следующей), и вы хотите отсортировать ее по ключу (дата здесь)

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

Использовать метод Array 'sort_by' как

data.sort_by { |element| element.keys.first }
Аби
источник