On Sep 14, 2007, at 8:42 AM, Dan Zwell wrote: > Axel Etzold wrote: >> Dear all, >> I have many arrays like >> a=[{'a',10,'b',3},{'a',10,'b',4},{'a',5,'b',13},{'a',13,'b',13}, >> {'a',10,'b',7},{'a',5,'b',3}] >> which I'd like to sort such that I get the hashes with the highest >> values of 'a' first. If there are ties, I'd like to sort them (but >> not >> the entire array) such >> that the highest values of 'b' come first. >> So I can't just sort for 'a'-values first and then for 'b'-values, >> as this would destroy the first sort order. >> Is there a built-in way of getting the ties in sorting, such as an >> Array of the results of the <=> comparisons ? >> Thank you! >> Best regards, >> Axel > > Built in? I don't know about that, but it's pretty easy. I'm sure > your real situation is more complex than the example you gave, but > I really think this is the easiest way (and you can avoid making > comparisons twice by caching the value of hash1['a'] <=> hash2 > ['a'], if you wish): > > a=[{'a',10,'b',3},{'a',10,'b',4},{'a',5,'b',13},{'a',13,'b',13}, > {'a',10,'b',7},{'a',5,'b',3}] > a.sort do |hash1, hash2| > if hash1['a'] == hash2['a'] > hash1['b'] <=> hash2['b'] > else > hash1['a'] <=> hash2['a'] > end > end > > The above is essentially a redefinition of <=> on hashes with > elements "a" and "b". The only thing you need to be sure of is that > ordering is strict--that you never have x < y < z but z < x. That > should be no problem if you only try to break ties. > > Hope this helps, > Dan a.sort do |h1,h2| (h1['a'] <=> h2['a']).nonzero? || h1['b'] <=> h2['b'] end The Numeric#nonzero? is exactly for this kind of thing. If its receiver is 0 it returns nil so chaining with || will work. (And you don't have to compare the 'a' values twice.) -Rob Rob Biedenharn http://agileconsultingllc.com Rob / AgileConsultingLLC.com