How to Sort a Hash by Value in Descending Order and Output a Hash in Ruby

How to sort a hash by value in descending order and output a hash in ruby?

Try:

Hash[h.sort.reverse]

This should return what you want.

Edit:

To do it by value:

Hash[h.sort_by{|k, v| v}.reverse]

Sort array of hashes by value of hash property in descending order preserving the initial order of hash

results = [
{ "rating"=>6, "id"=>10699 },
{ "rating"=>3, "id"=>19985 },
{ "rating"=>6, "id"=>1029 }
]

results.sort_by.with_index { |h,i| [-h["rating"], i] }
#=> [{"rating"=>6, "id"=>10699},
# {"rating"=>6, "id"=>1029}
# {"rating"=>3, "id"=>19985}]

See the third paragraph of the doc Array#<=> for an explanation of how Ruby orders arrays. When Ruby orders results[0] and results[2] she compares [-6, 0] with [-6, 2]. Because the first elements of these arrays are equal (-6), Ruby compares 0 with 2 to break the tie, so results[0] is ordered before results[2].

Note that when the method Enumerable#sort_by has no block, it returns an enumerator. Here that enumerator is chained to Enumerator#with_index to produce another enumerator.

Sorting Hash by value

Enumerable#sort_by never promised to sort the enumerable inplace. It returns the result:

puts mapa.sort_by {|a,b| -b}
#⇒ sorted

or, in more idiomatic manner:

mapa.sort_by(&:last).reverse.each do |k, v|
puts ...
end

Please note, that when examining the output in irb, the order might not correspond to the real order of elements in a hash, since irb (with print formatters installed) has it’s own ideas on how to output hashes.

How to sort a Ruby Hash by number value?

No idea how you got your results, since it would not sort by string value... You should reverse a1 and a2 in your example

Best way in any case (as per Mladen) is:

metrics = {"sitea.com" => 745, "siteb.com" => 9, "sitec.com" => 10 }
metrics.sort_by {|_key, value| value}
# ==> [["siteb.com", 9], ["sitec.com", 10], ["sitea.com", 745]]

If you need a hash as a result, you can use to_h (in Ruby 2.0+)

metrics.sort_by {|_key, value| value}.to_h
# ==> {"siteb.com" => 9, "sitec.com" => 10, "sitea.com", 745}

Descending sort by value of a Hash in Ruby

You can have it cleaner, clearer and faster, all at once! Like this:

h.sort_by {|k,v| v}.reverse

I benchmarked timings on 3000 iterations of sorting a 1000-element hash with random values, and got these times:

h.sort {|x,y| -(x[1]<=>y[1])} -- 16.7s
h.sort {|x,y| y[1] <=> x[1]} -- 12.3s
h.sort_by {|k,v| -v} -- 5.9s
h.sort_by {|k,v| v}.reverse -- 3.7

Sort array of hash by key in descending order in Ruby

You can do

h.sort_by! { |k| -k[:bookings_nd] }

or

h.sort_by! { |k| k[:bookings_nd] }.reverse!

Also i guess this question is duplicate for Sorting an array in descending order in Ruby

Sort hash by length of values (descending)

You cannot sort a hash - that might be causing your confusion. There is no "internal" ordering of elements of a hash as it appears in an array.

You can, however, iterate over a hash in a certain order, e.g.

hash.sort_by {|k,v| v.length}.reverse.each do |k, v|
puts "k = #{k}, v = #{v}"
end

How to sort a Ruby Hash alphabetically by keys

Assuming you want the output to be a hash which will iterate through keys in sorted order, then you are nearly there. Hash#sort_by returns an Array of Arrays, and the inner arrays are all two elements.

Ruby's Hash has a constructor that can consume this output.

Try this:

temp = Hash[ temp.sort_by { |key, val| key } ]

or more concisely

temp = temp.sort_by { |key| key }.to_h

If your hash has mixed key types, this will not work (Ruby will not automatically sort between Strings and Symbols for instance) and you will get an error message like comparison of Symbol with String failed (ArgumentError). If so, you could alter the above to

temp = Hash[ temp.sort_by { |key, val| key.to_s } ] 

to work around the issue. However be warned that the keys will still retain their original types which could cause problems with assumptions in later code. Also, most built-in classes support a .to_s method, so you may get unwanted results from that (such as unexpected sort order for numeric keys, or other unexpected types).

You could, in addition, convert the keys to Strings with something like this:

temp = Hash[ temp.map { |key, val| [key.to_s, val] }.sort ] 

. . . although this approach would lose information about the type of the original key making it impossible to refer back to the original data reliably.

Ruby sort by hash and value

Enumerable#sort_by to the rescue:

hash_data.sort_by { |hash| hash[:sortby] }
#=> [{:key1=>"valuedsd", :sortby=>1}, {:key1=>"value2_data_is_here", :sortby=>2}, {:key1=>"value4", :sortby=>4}, {:key1=>"valuesds6", :sortby=>6}]

If you don't care about initial object, I would suggest using Array#sort_by! to modify inplace - it is more resource-efficient:

hash_data.sort_by! { |hash| hash[:sortby] }

If you have different types of data as values to sortby key, you should first unify the data type and only then perform sorting.

To have array sorted in descending order, use Enumerable#reverse (or reverse!):

hash_data.sort_by {|hash| hash[:sortby] }.reverse
#=> [{:key1=>"valuesds6", :sortby=>6}, {:key1=>"value4", :sortby=>4}, {:key1=>"value2_data_is_here", :sortby=>2}, {:key1=>"valuedsd", :sortby=>1}]

Another option for sorting in descending order is the following - note minus sign (credits to @sagarpandya82):

hash_data.sort_by {|hash| -hash[:sortby] }


Related Topics



Leave a reply



Submit