On 14-Mar-06, at 5:03 PM, ara.t.howard / noaa.gov wrote:

> On Wed, 15 Mar 2006, Pavel Smerk wrote:
>
>> = how can I do 'perlish' a[1] <=> b[1] || a[2] <=> b[2] if I want  
>> compare a and b accordind to some my own rules, i.e. if a[1] == b 
>> [2], "return" a[2] <=> b[2]? In Ruby this is not possible, because  
>> 0 is true.
>
> because in ruby you don't have too:
>
>   a <=> b
>
> when a and b are arrays just does that.  if you wanted to compare  
> only the
> first elements (assuming there are more) you can simply
>
>   a[0,2] <=> b[0,2]
>
> or, if you a glutten for perlishment
>
>   [a[1], a[2]] <=> [b[0], b[1]]
>
>
> you can do __really__ compact sorting routines in ruby.  i wrote  
> one yesterday
> that sorts strings like this
>
>   /dmsp/nrt/data/incoming/afwa/2006.f13_0731556_DT.DAT
>   /dmsp/nrt/data/incoming/afwa/2006.f13_0731737_DS.DAT
>
> where
>
>   2006.f13_0731556_DT.DAT
>   ^^^^ ^^^ ^^^^^^^ ^^
>   |    |   |       |
>   year sat time    type
>
> first by sat, then by year, then by time and finally by type
>
> using only
>
>   pats = %w[  f\d\d  ^\d{4}  _\d{7}  _\w{2}  ].map{|p|/#{p}/}
>
>   basenames.sort!{|a,b| pats.map{|pat| a[pat]} <=> pats.map{|pat| b 
> [pat]} }
>
> gotta love that!!

Tangentially speaking you can use unpack and sort_by to do this kind  
of thing if it suits the situation (admittedly there's not a  
sort_by!, but let's not let that get in the way :-)

sorted_basenames = basenames.sort_by { |name|
   name.unpack('A4 x A3 x A7 x A2').values_at(1, 0, 2, 3)
}

or the delightful

sorted_basenames = basenames.sort_by { |name| name.unpack('x5 A3 X8  
A4 x5 A7 x A2') }

This is just an excuse to expose unpack and sort_by to people, not a  
suggestion that it's necessarily appropriate or better in this case.

Mike

-- 

Mike Stok <mike / stok.ca>
http://www.stok.ca/~mike/

The "`Stok' disclaimers" apply.