How to sort not simple hash (hash of hashes)

前端 未结 3 872
执笔经年
执笔经年 2021-02-04 20:20

I have a Hash like this

{ 55 => {:value=>61, :rating=>-147},
  89 => {:value=>72, :rating=>-175},
  78 => {:value=>64, :rating=>-155},         


        
相关标签:
3条回答
  • 2021-02-04 20:36

    Hashes in Ruby can't be sorted (at least not before 1.9)

    This means that looping through a Hash won't necessarily yield the information in the right order for you. However, it's trivial to loop through Hashed data in a particular order by converting it to an Array first, and in fact calling the sort methods on a Hash will convert 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] }
    
    0 讨论(0)
  • 2021-02-04 20:48

    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 sort this kind of structure easily with

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

    To get the hash-like functionality of fetching a record by id you can define a new method on my_array:

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

    so after that you can do

    my_array.find_by_id(id)
    

    instead of

    my_hash[id]
    
    0 讨论(0)
  • 2021-02-04 20:56

    There might be a better data structure, but (I'm assuming this is ruby) it's possible to do in Ruby by using the inline sort style to basically tell it how to compare the two. Here's 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
    
    0 讨论(0)
提交回复
热议问题