I have an array of hashes:
[
{ :foo => 'foo', :bar => 2 },
{ :foo => 'foo', :bar => 3 },
{ :foo => 'foo', :bar => 5 },
]
I am trying to sort this array in descending order according to the value of :bar
in each hash.
I am using sort_by
to sort above array:
a.sort_by { |h| h[:bar] }
However, this sorts the array in ascending order. How do I make it sort in descending order?
One solution was to do following:
a.sort_by { |h| -h[:bar] }
But that negative sign does not seem appropriate.
Best Answer
It's always enlightening to do a benchmark on the various suggested answers. Here's what I found out:
I think it's interesting that @Pablo's
sort_by{...}.reverse!
is fastest. Before running the test I thought it would be slower than "-a[:bar]
" but negating the value turns out to take longer than it does to reverse the entire array in one pass. It's not much of a difference, but every little speed-up helps.Here are results for Ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-darwin10.8.0]:
These are on an old MacBook Pro. Newer, or faster machines, will have lower values, but the relative differences will remain.
Here's a bit updated version on newer hardware and the 2.1.1 version of Ruby:
New results running the above code using Ruby 2.2.1 on a more recent Macbook Pro. Again, the exact numbers aren't important, it's their relationships:
Updated for Ruby 2.7.1 on a Mid-2015 MacBook Pro:
The source for
Array#reverse
is:do *p2-- = *p1++; while (--len > 0);
is copying the pointers to the elements in reverse order if I remember my C correctly, so the array is reversed.