2008-12-12 3 views
4

У меня есть Hash, как этотКак сортировать не простой хэш (хэш хэшей)

{ 55 => {:value=>61, :rating=>-147}, 
    89 => {:value=>72, :rating=>-175}, 
    78 => {:value=>64, :rating=>-155}, 
    84 => {:value=>90, :rating=>-220}, 
    95 => {:value=>39, :rating=>-92}, 
    46 => {:value=>97, :rating=>-237}, 
    52 => {:value=>73, :rating=>-177}, 
    64 => {:value=>69, :rating=>-167}, 
    86 => {:value=>68, :rating=>-165}, 
    53 => {:value=>20, :rating=>-45} 
} 

Как я могу сортировать его : рейтинг? Или, может быть, я должен использовать какую-то другую структуру?

+1

Вероятно, стоит отметить язык программирования в названии. – danieltalsky 2008-12-12 07:46:34

ответ

5

Я хотел бы изменить структуру данных в массив хэшей:

my_array = 
[ 
    {:id => 78, :value=>64, :rating=>-155}, 
    {:id => 84, :value=>90, :rating=>-220}, 
    {:id => 95, :value=>39, :rating=>-92} 
] 

Вы можете сортировать этот вид структуры легко с

my_array.sort_by { |record| record[:rating] } 

Чтобы получить хэш-подобная функция выборки по идентификатору вы можете определить новый метод на my_array:

def my_array.find_by_id(id) 
    self.find { |hash| hash[:id] == id } 
end 

так после того, что вы можете сделать

my_array.find_by_id(id) 

вместо

my_hash[id] 
+0

Не уверен, будет ли ответ на этот комментарий через 4 года .... Причина, по которой я использую хэш, - это использовать ключ, к которому я могу напрямую обращаться, и увеличивать значения, например h [436246]. После того, как я заполнил хэш, я должен преобразовать в массив – nilanjan 2013-01-04 14:39:33

5

хэши в Ruby, не могут быть отсортированы (по крайней мере, до 1,9)

Это означает, что цикл через Hash не обязательно дают информацию в правильном порядке для вас. Тем не менее, это тривиальное Переберите беспорядочных данных в определенном порядке путем преобразования его в массив первой, и на самом деле вызова методов сортировки по Hash преобразует его в массив для вас:

>> { :a => 4, :b => 12, :c => 3, :d => 8 }.sort_by { |key, value| value } 
=> [[:c, 3], [:a, 4], [:d, 8], [:b, 12]] 

Так что в вашем случай:

hsh.sort_by {|key, ratings| ratings[:rating] } 
+0

@Gaius - спасибо за редактирование, но код работает так, как написано. Все дело в том, что #sort_by неявно преобразует Array без необходимости вставлять .to_a в - даже в Ruby 1.8 – Gareth 2008-12-13 09:55:47

3

Там может быть лучше структура данных, но (я предполагаю, что это рубин), что можно сделать в Ruby, используя встроенный стиль сортировки в основном это сказать, как сравнить два. Вот конкретный пример:

my_hash = { 
    55 => {:value=>61, :rating=>-147}, 
    89 => {:value=>72, :rating=>-175}, 
    78 => {:value=>64, :rating=>-155}, 
    84 => {:value=>90, :rating=>-220}, 
    95 => {:value=>39, :rating=>-92}, 
    46 => {:value=>97, :rating=>-237}, 
    52 => {:value=>73, :rating=>-177}, 
    64 => {:value=>69, :rating=>-167}, 
    86 => {:value=>68, :rating=>-165}, 
    53 => {:value=>20, :rating=>-45} 
} 

puts "MY HASH" 
my_hash.each do |local| 
    puts local 
end 

sorted_hash = my_hash.sort { | leftval, rightval | rightval[1][:rating]<=>leftval[1][:rating] } 

puts "SORTED HASH" 
sorted_hash.each do |local| 
    puts local 
end 
+0

Здесь здесь не будет иметь большого значения, но #sort обычно неэффективна с вычисленными полями. Это связано с тем, что он пересчитывает критерии сортировки для * каждого * сравнения. #sort_by вычисляет критерии только один раз для каждого элемента в исходном массиве – Gareth 2008-12-12 07:56:35

Смежные вопросы