Afficher un message
Vieux 14/09/2007, 15h09   #4
Rob Biedenharn
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Finding ties in sorting?

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 s,
> 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



  Réponse avec citation
 
Page generated in 0,05847 seconds with 9 queries