Robert Klemme
7/16/2005 7:39:00 AM
Garance A Drosehn <drosihn@gmail.com> wrote:
> On 7/15/05, Ara.T.Howard <Ara.T.Howard@noaa.gov> wrote:
>> On Sat, 16 Jul 2005, Garance A Drosehn wrote:
>>
>>> 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? ...
>>
>> [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
>
> Ooo. Very nice. Thanks!
>
> The suggestions to look at sort_by (from Enumerable) and
> the idea of: (vals[kb] <=> vals[ka]).nonzero? or (ka <=> kb)
> were also very useful. Thanks to all.
Noone explicitely commented on the use of hash.keys.sort: this is quite
inefficient. Instead doing the sort on the hash directly is much more
efficient:
>> hash = { "a" => 1, "b" => 4, "c" => 3, "d" => 1 }
=> {"a"=>1, "b"=>4, "c"=>3, "d"=>1}
>> hash.sort {|a,b| a.reverse <=> b.reverse}
=> [["a", 1], ["d", 1], ["c", 3], ["b", 4]]
This technique can be applied to sort_by, too:
>> hash.sort_by {|a| a.reverse}
=> [["a", 1], ["d", 1], ["c", 3], ["b", 4]]
But this shows a strange anomaly - this seems like a bug in 1.8.2.
>> hash.sort_by {|a| a.reverse!}
=> [[1, "a"], [1, "d"], [3, "c"], [4, "b"]]
You can also directly chain printing:
>> hash.sort_by {|a| a.reverse}.each {|k,v| printf "%3d %s\n", v, k}
1 a
1 d
3 c
4 b
=> [["a", 1], ["d", 1], ["c", 3], ["b", 4]]
Kind regards
robert