From: Daniel Sheppard Date: 2006-10-30T10:18:32+09:00 Subject: Re: How can i do 'foreach (reverse sort { $hasref->{$a} <=> $hasref->{$b} } keys %{$hasref})..' in ruby > For the archive: > > My working line is know: > > clients.sort{|(k1,v1),(k2,v2)| v2 <=> v1}.each{|k,v| > printf("% 7i %s\n",v, k) > } For the simple case (such as yours) where the values being sorted are numeric, I find it neater to just do: clients.sort_by{|k,v| -v}.each {|k,v| printf("% 7i %s\n",v, k) } Or in the general case: clients.sort_by{|k,v| v}.reverse.each {|k,v| printf("% 7i %s\n",v, k) } Or: clients.sort_by{|k,v| v}.reverse_each {|k,v| printf("% 7i %s\n",v, k) } Which is probably clearest in intention (looking at the original code you post, it's not immediately apparent the it's a reverse sort). These methods have the added benefit of also being the faster code (sort_by is much faster than sort). require 'benchmark' hash = {} 1_000_000.times {|i| hash[i] = rand} Benchmark.bm(22) {|bm| bm.report('sort') {hash.sort{|(k1,v1),(k2,v2)| v2 <=> v1}.each{|k,v|}} bm.report('sort_by @-') {hash.sort_by{|k,v| -v}.each {|k,v|}} bm.report('sort_by reverse') {hash.sort_by{|k,v| v}.reverse.each {|k,v|}} bm.report('sort_by reverse_each') {hash.sort_by{|k,v| v}.reverse_each {|k,v|}} } user system total real sort 58.094000 0.719000 58.813000 ( 99.922000) sort_by @- 10.297000 0.046000 10.343000 ( 14.750000) sort_by reverse 10.922000 0.063000 10.985000 ( 14.687000) sort_by reverse_each 10.000000 0.016000 10.016000 ( 12.094000)