I have an array of hashes like following
[
{ :foo => 'foo', :bar => 2 },
{ :foo => 'foo', :bar => 3 },
{ :foo => 'foo', :bar => 5 },
]
I am trying to sort above array in descending order according to the value of :bar
in each hash.
I am using sort_by
like following to sort above array.
a.sort_by { |h| h[:bar] }
However above 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. Any views?
You could do:
Just a quick thing, that denotes the intent of descending order.
(Will think of a better way in the mean time) ;)
Regarding the benchmark suite mentioned... these results also hold for sorted arrays. sort_by / reverse it is :)
Eg:
And the results:
What about:
It works!!
I see that we have (beside others) basically two options:
and
While both ways give you the same result when your sorting key is unique, keep in mind that the
reverse
way will reverse the order of keys that are equal.Example:
While you often don't need to care about this, sometimes you do. To avoid such behavior you could introduce a second sorting key (that for sure needs to be unique at least for all items that have the same sorting key):
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: