zengr
zengr

Reputation: 38899

Descending sort by value of a Hash in Ruby

My input hash: h = { "a" => 20, "b" => 30, "c" => 10 }

Ascending sort: h.sort {|a,b| a[1]<=>b[1]} #=> [["c", 10], ["a", 20], ["b", 30]]

But, I need [["b", 30], ["a", 20], ["c", 10]]

How is can we make it work the other way around, what does <=> mean?

Upvotes: 84

Views: 65856

Answers (4)

Paul Odeon
Paul Odeon

Reputation: 4524

Super simple: h.sort_by { |k, v| -v }

Upvotes: 12

glenn mcdonald
glenn mcdonald

Reputation: 15478

You can have it cleaner, clearer and faster, all at once! Like this:

h.sort_by {|k,v| v}.reverse

I benchmarked timings on 3000 iterations of sorting a 1000-element hash with random values, and got these times:

h.sort {|x,y| -(x[1]<=>y[1])} -- 16.7s
h.sort {|x,y| y[1] <=> x[1]} -- 12.3s
h.sort_by {|k,v| -v} -- 5.9s
h.sort_by {|k,v| v}.reverse -- 3.7

Upvotes: 205

ceth
ceth

Reputation: 45295

h.sort {|a,b| b[1]<=>a[1]}

Upvotes: 12

Chuck
Chuck

Reputation: 237010

<=> compares the two operands, returning -1 if the first is lower, 0 if they're equal and 1 if the first is higher. This means that you can just do -(a[1]<=>b[1]) to reverse the order.

Upvotes: 10

Related Questions