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}
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]
How to sort hash keys by their value in ruby 2.3.0
You can't change the order of a hash, but you can sort the array before turning it into a hash:
data = [
['Frank', 33],
['Stacy', 15],
['Juan', 24],
['Dom', 32],
['Steve', 24],
['Jill', 24]
]
hash = data.sort_by(&:last).to_h
# => { "Stacy" => 15,
# "Juan" => 24,
# "Steve" => 24,
# "Jill" => 24,
# "Dom" => 32,
# "Frank" => 33 }
If you already have a hash, then you'll have to turn it into an array, then sort it, and then turn it back into a hash, e.g. hash.to_a.sort_by(&:last).to_h
.
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 hash by the values of another array in Ruby?
You don't need to sort anything, and you also don't need to create a lookup table. Your array is already sorted the way you want and your sort_me
hash is already a lookup table:
elements = ['one', 'two', 'three']
# => ["one", "two", "three"]
sort_me = {'three' => 3, 'two' => 2, 'one' => 1}
# => {"three"=>3, "two"=>2, "one"=>1}
elements.map{|key| [key, sort_me[key] ] }.to_h
# => {"one"=>1, "two"=>2, "three"=>3}
If you want to use symbols and strings:
elements = ['one', 'two', 'three']
# => ["one", "two", "three"]
sort_me = {three: 3, two: 2, one: 1}
# => {:three=>3, :two=>2, :one=>1}
elements.map{|key| [key.to_sym, sort_me[key.to_sym] ] }.to_h
# => {:one=>1, :two=>2, :three=>3}
Finally, if some elements
are not used in the hash, you could simply remove pairs with nil
values:
elements = ['one', 'two', 'two_and_a_half', 'three']
# => ["one", "two", "two_and_a_half", "three"]
elements.map{|key| [key.to_sym, sort_me[key.to_sym] ] }.to_h
# => {:one=>1, :two=>2, :two_and_a_half=>nil, :three=>3}
elements.map{|key| [key.to_sym, sort_me[key.to_sym] ] }.reject{|k, v| v.nil? }.to_h
# => {:one=>1, :two=>2, :three=>3}
Sorting a Hash by integer value of hash key in Ruby 1.9
Nice and simple (for 1.9):
hs = Hash[h.sort_by {|k,v| k.to_i }]
For example:
>> h = { '23' => 'twenty three', '11' => 'eleven', '42' => 'forty two', '1' => 'one' }
=> {"23"=>"twenty three", "11"=>"eleven", "42"=>"forty two", "1"=>"one"}
>> hs = Hash[h.sort_by {|k,v| k.to_i }]
=> {"1"=>"one", "11"=>"eleven", "23"=>"twenty three", "42"=>"forty two"}
And for more recent Rubies:
hs = h.sort_by { |k, _| k.to_i }.to_h
How to sort a hash by values
You can use ActiveSupport::OrderedHash
for Ruby 1.8:
ActiveSupport::OrderedHash
implements a hash that preserves insertion order, as in Ruby 1.9
I don't have 1.8.6 running, but this should work:
a = {}
a[0] = "c"
a[1] = "b"
a[2] = "a"
ordered = ActiveSupport::OrderedHash[*a.sort_by{|k,v| v}.flatten]
ordered.keys
# => [2, 1, 0], this order is guaranteed
As noted in the quote above hashes in Ruby 1.9 "enumerate their values in the order that the corresponding keys were inserted", so this is only needed for Ruby 1.8.
Sorting a hash in Ruby by its value first then its key
Try this:
Assuming:
a = {
'the' => '6',
'we' => '7',
'those' => '5',
'have' => '3',
'hav' => '3',
'haven' => '3'
}
then after doing this:
b = a.sort_by { |x, y| [ -Integer(y), x ] }
b
will look like this:
[
["we", "7"],
["the", "6"],
["those", "5"],
["hav", "3"],
["have", "3"],
["haven", "3"]
]
Edited to sort by reverse frequencies.
Related Topics
How to Change All the Keys of a Hash by a New Set of Given Keys
How Can an Activerecord::Relation Object Call Class Methods
Geocoder, How to Test Locally When Ip Is 127.0.0.1
What to Use Instead of 'Render :Text' (And 'Render Nothing: True') in Rails 5.1 and Later
Ruby on Rails: How to Explicitly Define Plural Names and Singular Names in Rails
How to Read the Content of an Excel Spreadsheet Using Ruby
Rails 3. How to Display Two Decimal Places in Edit Form
Activerecord - Querying Polymorphic Associations
Differencebetween 'After_Create' and 'After_Save' and When to Use Which
Gem.Source_Index Is Deprecated, Use Specification. Should I Re-Install Gem or Rails
Get the Value of an Instance Variable Given Its Name
How to Make Instance Variables Private in Ruby
How to Print Out the Contents of an Object in Rails for Easy Debugging
Using Instance Variables in Class Methods - Ruby