From: Robert Klemme Date: 2012-01-19T21:56:22+09:00 Subject: Re: Elegant expression of sorting On Thu, Jan 19, 2012 at 11:49 AM, Garthy D wrote: > On 19/01/12 19:52, Robert Klemme wrote: >> foo.sort! {|a,b| >>  # Ascending, primary. >>  (a.key0<=>  b.key0).nonzer0? || >>  # Descending, secondary. >>  (b.key1<=>  a.key1).nonzero? || >>  # A tricky and expensive comparison, tertiary. >>  a.magic(b) >> } > > > Very, very neat; and nice find on "nonzero?". :) My first thought was that > "nonzero?" surely returns a boolean and this would break it- but it looks > like "nonzero?" with numeric return was designed for this *exact* problem. > :) Right. :-) > I was wondering if there was a nice way to drop the "rv" from my solution- > this looks like the best way. > > >> foo.sort_by {|a| >>   [ >>   # Ascending, primary. >>   a.key0, >>   # Descending, secondary, only if numeric. >>   -a.key1, >>    # A tricky and expensive comparison, tertiary. >>   a.create_magic_key >>   ] >> } > > I'd stumbled on sort_by initially, I suspect I'll use it when I can > precompute the comparisons easily (this is sometimes the case, sometimes > not). Note, with #sort_by you do not precompute comparisons but you compute a comparison key! In the example it is an Array because Array#<=> uses fields from the beginning to the end, i.e. sorts according to fields with decreasing precedence (first pos 0, if that comparison returns 0 field pos 1 etc.). > I'm not at all familiar with the "enum.sort_by&YourClass::SORT_FOO" syntax > at this point, so I might need to read up on that. I can at least partly > guess from the context though. It just passes the lambda as a block as if it the block was passed directly. Note, that technically behind the scenes the syntax foo(&x) invokes x.to_proc which is also provided by Symbol: irb(main):001:0> a = 5.times.to_a => [0, 1, 2, 3, 4] irb(main):002:0> a.map {|x| x.to_s} => ["0", "1", "2", "3", "4"] irb(main):003:0> a.map(&:to_s) => ["0", "1", "2", "3", "4"] > Thankyou for your very detailed input on this one, excellent stuff! :) You're welcome! Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/