How do you sort a hash in ruby based on the value and then key? For example
h = {4 => 5, 2 => 5, 7 => 1}
would sort into
[[7, 1], [2,5], [4, 5]]
I can sort based on the value by doing
h.sort {|x,y| x[1] <=> y[1]}
but I can't开发者_开发知识库 figure out how to sort based on value and then key if the values are the same
h.sort_by {|k, v| [v, k] }
This uses the fact that Array
mixes in Comparable
and defines <=>
element-wise.
Note that the above is equivalent to
h.sort_by {|el| el.reverse }
which is equivalent to
h.sort_by(&:reverse)
which may or may not be more readable.
If you know that Hash
es usually sort by key first, then by value, the above should be obvious. Maybe with a small comment:
h.sort_by(&:reverse) # sort by value first, then by key
Note: if you simply want to delegate to some property's <=>
method, (i.e. sort by a key rather than a general comparison function) it is generally prefered to use sort_by
instead of sort
. It's much easier to read. Generally, it also happens to be faster, but the readability aspect is the more important one.
You should really only write your own comparison function if absolutely necessary.
So, your non-working example would better be written as
h.sort_by {|el| el[1] }
Personally, I prefer to use destructuring bind in the block parameter list, instead of using el[0]
and el[1]
:
h.sort_by {|key, value| value }
However, in this particular case, el[1]
also happens to be identical to el.last
, so that you could simply write
h.sort_by(&:last)
精彩评论