tags:

views:

169

answers:

4

I usually do something like

array.sort{|a,b| a.something <=> b.something}

How should I DRY this up?

+12  A: 

use sort_by

array.sort_by{|e| e.something}

or

sort_lambda = lambda{|e| e.something}
array.sort_by(&sort_lambda)

With latter you can reuse sort_lambda in other sort_by statements

Eimantas
+3  A: 

In Rails, or rather with ActiveSupport, or in Ruby 1.9 (possibly 1.8.7, not sure) you can use the new short-cut hotness:

array.sort_by(&:something)

Note that sort_by has possibly expensive (and possibly beneficial: it depends on sort key complexity) side-effects: it generates and stores a temporary key-value pair for each item so that it can sort by your new key. See the discussion in the documentation for more on this.

Mike Woodhouse
Yep, Ruby 1.8.7 has Symbol#to_proc.
Chuck
Would be nice if array.sort_on(:something) worked as well.
tadman
Chuck
+3  A: 

+1 to both of Eimantas' suggestions, but I often have this come up in cases where I have a custom class that always sorts this way, like Albums that should sort case-insensitively, ignoring leading punctuation and the/a/an. For that use it's more efficient to calculate the sort value once, and then redefine <=> accordingly. E.g.:

class Album
 def sort_value
    @sv ||= @name.downcase.sub(/^\W*(the|an|a) /,"")
  end

  def <=>(other)
    sort_value <=> (other.sort_value rescue other)
  end
end
glenn mcdonald
A: 

Have you considered including Comparable in the class for a and b, and just calling sort?

krdluzni