From: Jan Svitok Date: 2007-01-10T00:26:27+09:00 Subject: Re: sortung a structured array on more than one criteria On 1/9/07, dblack@wobblini.net wrote: > Hi -- > On Wed, 10 Jan 2007, Josselin wrote: > > > On 2007-01-09 15:53:13 +0100, "Jan Svitok" said: > > > >> On 1/9/07, Josselin wrote: > >>> On 2007-01-09 15:29:43 +0100, Josselin said: > >>> > >>> > I can sort an array like that : > >>> > > >>> > results = rs.sort_by{|p| p.km} > >>> > > >>> > but I tried to add a scrond sorting criteria like that : > >>> > > >>> > results = rs.sort_by{|p| p.km, p.updated_at } > >>> > > >>> > and I got obviously an error ... parse error, unexpected '}', > >>> > expecting tCOLON2 or '[' or '.' > >>> > > >>> > canot find the correct writing.. > >>> > > >>> > appreciate any help... > >>> > > >>> > thanks > >>> > > >>> > joss > >>> > >>> thanks to both of you... and HNY%2007 (Dry version of Happy New Year > >>> 2007) ;-)) > >>> > >>> I forgot to ask about a DESC sort.... p.km is Ascending and > >>> p.updated_at should be DESC.. > >>> > >>> I am not sure that is possible (at least not documented.....) > >>> > >>> joss > >> > >> results = rs.sort_by{|p| p.km, -p.updated_at } # if updated_at is Numeric > >> > >> or > >> > >> results = rs.sort { |a,b| [a.km, b.updated_at] <=> [b.km, a.updated_at] } > > > > thanks , 'updated_at' is a string ( "2007-01-04 13:48:30") > > I try to understand the writing... why the first parameter will be Ascending > > and the second Descending ... > > > > how would you write it, if both parameters shoudl be Descending ? > > results = rs.sort_by {...}.reverse Ok, two things: 1. how does my code works: The block in sort {|x,y| } implements x<=>y (<=>, comparison operator, sometimes called starship operator, returns -1, 0 or 1 for x y) [a,b] <=> [c,d] (array comparision) is implemented as first doing a<=>c and if they are equal doing b<=>d. if I exchange b and d, I effectively reverse the result of the second comparision. If I wanted the reverse sort, I could exchange both pairs, i.e. instead of doing x<=>y I'd be doing y <=> x. 2. sort_by is usually faster than sort because it does n block evaluations, while sort does O(n*n) evaluations. Therefore sort_by {}.reverse is usually better than sort{|a,b| b<=> a} (except some edge cases where computaton is fast, and the block's result is large)