From: "David A. Black" Date: 2005-07-16T11:53:23+09:00 Subject: Re: Cascading <=> comparisons Hi -- On Sat, 16 Jul 2005, Garance A Drosehn wrote: > Let's say I have a hash with some values in it, and I want to > print out that hash in some sort order. I can: > > korder = vals.keys.sort { |ka, kb| > vals[kb] <=> vals[ka] > } > korder.each { |key| printf " %3d - %s\n", vals[key], key } > > That's pretty easy, but what if I want to cascade comparisons > in that sort, such that if the data-values are equal, then I want > the sort order to be based on some other comparison? It > seems to me that I have to: > > korder = vals.keys.sort { |ka, kb| > sres = vals[kb] <=> vals[ka] > sres = ka <=> kb if sres == 0 > sres > } > korder.each { |key| printf " %3d - %s\n", vals[key], key } You can use sort_by and put your sort keys in an array. For example, this sorts a hash by value and then by key: hash = { "a" => 1, "b" => 4, "c" => 3, "d" => 1 } p hash.sort_by {|k,v| [v,k] } => [["a", 1], ["d", 1], ["c", 3], ["b", 4]] David -- David A. Black dblack@wobblini.net