tags:

views:

125

answers:

2

What's the best way to sort an Enumerable in descending order?

I've been doing @array.sort.reverse or @array.sort_by{|song| song.title }.reverse

I suppose I could do something like @array.sort{|a, b| b.title <=> a.title}, but I find this hard to read and verbose.

+3  A: 

The performance of Array.reverse is not very bad. What costs you by using @array.sort.reverse is an extra array duplication plus the reverse (n/2 element switches). So yes, I think that should be acceptable if you think it's read clearer.

See its source for details. And also, I think using @array.sort.reverse does provide 'slightly' better readability (but it's not very hard to read any way).

bryantsai
sort.reverse is not much slower than sort, and it's way faster than anything fancy. I benchmarked array.sort, array.sort.reverse, and array.reverse_sort (my monkey-patch solution, which I've since deleted as "an obvious piece of junk") on 1,000,000 random floats and got times of 2.4, 2.5 and 24.8 seconds, respectively.
Wayne Conrad
+2  A: 

I'm not sure whether this works any better than Wayne Conrad's self-described "obvious piece of junk," but you could define Enumerable#sort_by_descending as

Enumerable.class_eval do
  def sort_by_descending(&block)
    sort { |a, b| block.bind(b).call <=> block.bind(a).call }
  end
end

Then call it as follows:

@songs.sort_by_descending(&:title)
James A. Rosen