Sortung a structured array on more than one criteria

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

On Jan 9, 2007, at 8:30 AM, Josselin wrote:

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 }

results = rs.sort_by { |p| [p.km, p.updated_at] }

Arrays can be sorted and will compare their contents in order, so
this should do what you want.

Hope that helps.

James Edward G. II

Hi –

On Tue, 9 Jan 2007, Josselin wrote:

canot find the correct writing…

Try this:

results = rs.sort_by {|p| [p.km, p.updated_at] }

David

On 09/01/07, Josselin [email protected] wrote:

canot find the correct writing…

appreciate any help…

thanks

joss

results = rs.sort_by{|p| [p.km,p.updated_at]}

Farrel

On 2007-01-09 15:29:43 +0100, Josselin [email protected] said:

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

On 2007-01-09 15:53:13 +0100, “Jan S.” [email protected] said:

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 ?

Joss

Hi –

On Tue, 9 Jan 2007, Josselin wrote:

thanks to both of you… and HNY%2007 (Dry version of Happy New Year 2007)
;-))

Actually Happy New Year 2007 is already pretty DRY, although it does
use two 0’s… :slight_smile: Yours is more like the golf version :slight_smile:

David

On 1/9/07, Josselin [email protected] wrote:

and I got obviously an error … parse error, unexpected ‘}’,
thanks to both of you… and HNY%2007 (Dry version of Happy New Year

  1. ;-))

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]
}

Hi –
On Wed, 10 Jan 2007, Josselin wrote:

joss

how would you write it, if both parameters shoudl be Descending ?

results = rs.sort_by {…}.reverse

David

On 1/9/07, [email protected] [email protected] wrote:

results = rs.sort_by{|p| p.km}
appreciate any help…

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, x==y
and 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.

  1. 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)

On Jan 9, 2007, at 8:30 AM, Josselin wrote:

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 }

Try this.

results = rs.sort_by { |p| [p.km, p.updated_at] }

This way you’re sorting arrays containing each of the sort criteria.