1
example_hash = {
  "1" => {"occurence": 12, "display": ""},
  "2" => {"occurence": 15, "display": ""},
  "3" => {"occurence": 16, "display": ""}
}

For the given above nested hash, how do we sort (descending) it based on the occurrence value. The result should display the keys in the sorted order [3,2,1]

Leo Correa
  • 19,131
  • 2
  • 53
  • 71
Lollypop
  • 251
  • 1
  • 5
  • 14
  • `example_hash.sort_by{|k, v| v[:occurence]}.reverse!.to_h` – jedi Jul 24 '18 at 21:21
  • Possible duplicate of [How to sort a Ruby Hash by number value?](https://stackoverflow.com/questions/2540435/how-to-sort-a-ruby-hash-by-number-value) – jedi Jul 24 '18 at 21:23

2 Answers2

4
example_hash.sort_by { |_,h| -h[:occurrence] }
  #=> [["3", {:occurrence=>16, :display=>""}],
  #    ["2", {:occurrence=>15, :display=>""}],
  #    ["1", {:occurrence=>12, :display=>""}]]

Tack on .to_h if a hash is desired, but one does not normally desire a hash with keys sorted in a particular way.

Cary Swoveland
  • 106,649
  • 6
  • 63
  • 100
  • SHAZAM! For us knuckle heads that are still ham fisting with `sort{|a,b| ...}`, could you say a little more about that syntax? – jvillian Jul 24 '18 at 23:47
  • @jvillian, there's not much to say, it's just the method [Enumerable#sort_by](http://ruby-doc.org/core-2.4.0/Enumerable.html#method-i-sort_by). One advantage of that over `sort` is that `h["occurrence"]` is calculated just once for each value (hash), rather than twice for each pairwise-comparison with `sort`. – Cary Swoveland Jul 25 '18 at 00:59
  • I suppose I was thrown by the underscore in the `|_,h|` bit. How does that underscore work? Also, the `-h[:occurrence]`. I guess the `-` in front of the `h` means descending? – jvillian Jul 25 '18 at 01:02
  • 2
    @jvillian, one Ruby convention is to represent a block variable with an underscore when it's not used in the block calculation ('hey, reader I'm not using this variable in this block"). Here that variable represents a hash key. While `_` is a valid local variable, it differs from variable names that do not begin with an underscore in that Ruby allows it to be used to represent more than one local variable (e.g., `{ |_,_,x|...}` or `_,x,_ = [1,2,3]`). Sometimes you might see `{ |_k,h|...}` when `_k` is not used. – Cary Swoveland Jul 25 '18 at 01:16
1

In console, this:

example_hash.sort{|a,b| b[1][:occurence] <=> a[1][:occurence]}.to_h

returns this:

{"3"=>{:occurence=>16, :display=>""}, "2"=>{:occurence=>15, :display=>""}, "1"=>{:occurence=>12, :display=>""}}

BTW, I believe you've misspelled 'occurence'.

jvillian
  • 19,953
  • 5
  • 31
  • 44