From: "Ara.T.Howard" Date: 2005-07-16T12:34:18+09:00 Subject: Re: Cascading <=> comparisons 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 } > > In perl, I can just casade the '<=>' comparisons, because it > will treat the zero value as "false". Thus, I could get away > with a one-liner somewhat similar to: > > vals[kb] <=> vals[ka] or a <=> kb [vals[kb], ka] <=> [vals[ka], kb] note that the array approach scales for any number of things, not only two. you can always do [a,b,c] <=> [x,y,z] even if a, b, and c are different types. so long as you can a <=> x b <=> y c <=> z hth. -a -- =============================================================================== | email :: ara [dot] t [dot] howard [at] noaa [dot] gov | phone :: 303.497.6469 | My religion is very simple. My religion is kindness. | --Tenzin Gyatso ===============================================================================