ParkerCP
ParkerCP

Reputation: 31

How to sort hash keys by their value in ruby 2.3.0

I have this array:

data = [
  ['Frank', 33],
  ['Stacy', 15],
  ['Juan', 24],
  ['Dom', 32],
  ['Steve', 24],
  ['Jill', 24]
]

I took that and turned it into a hash so that I would have it be organized by keys and values, so that they would be easier to call individually. Which ended up giving me this

{"Frank"=>33, "Stacy"=>15, "Juan"=>24, "Dom"=>32, "Steve"=>24, "Jill"=>24}

I know in order to only see the keys I need to do data.keys and that by doing data.keys.sort I get the keys in alphabetical order.

I assume that I need to do something like data.keys.sort_by { |key, value| value } but whenever I run that I receive the hash keys in the original order.

Upvotes: 2

Views: 4454

Answers (2)

Shiva
Shiva

Reputation: 12514

Additionally,

How to sort hash keys by their value in ruby 2.3.0?

if you have a hash like

hash = {"Frank"=>33, "Stacy"=>15, "Juan"=>24, "Dom"=>32, "Steve"=>24, "Jill"=>24}

then, hash can be simply sorted by keys or values but this will give you an array or arrays which can be converted to hash though.

hash.sort_by{|x,y| y}.to_h
# => {"Stacy"=>15, "Juan"=>24, "Steve"=>24, "Jill"=>24, "Dom"=>32, "Frank"=>33}

For nested hashes

people = {
  :fred => { :name => "Fred", :age => 23 },
  :joan => { :name => "Joan", :age => 18 },
  :pete => { :name => "Pete", :age => 54 }
}

people.sort_by { |k, v| v[:age] }
# => [[:joan, {:name=>"Joan", :age=>18}],
#     [:fred, {:name=>"Fred", :age=>23}],
#     [:pete, {:name=>"Pete", :age=>54}]]

In this way, we could even sort by the :name key, if we so chose.

Upvotes: 3

Jordan Running
Jordan Running

Reputation: 106027

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.

Upvotes: 4

Related Questions