How to sort a non-simple hash (hash hash)

I have a hash like this

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

How can I sort it by : rating ? Or maybe I should use some other structure?

+4
source share
3 answers

I would change the data structure to an array of hashes:

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

You can easily sort this structure with

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

To get a hash-like function to get the record by id, you can define a new method in my_array:

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

after which you can do

 my_array.find_by_id(id) 

instead

 my_hash[id] 
+5
source

Ruby hashes cannot be sorted (at least not earlier than 1.9)

This means that looping through a hash will not necessarily give you the information in the correct order. However, it is trivial to iterate over the hashed data in a specific order, first converting it to an array, and actually calling the hash sorting methods will turn it into an array for you:

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

So in your case:

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

Maybe a better data structure, but (I assume it is a ruby), this can be done in Ruby using the built-in sorting style to basically tell how to compare the two. Here is a concrete example:

 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 
+3
source

All Articles