Ruby Hashes Cheat Guide for Beginners

Published: 2014-08- 5

Once you have Arrays under your wing, then the next step is Hashes. Where Arrays are just a list of items, Hashes are a list of key/values which make them even more powerful for storing data.
Here are the methods I use regularly when dealing with Hashes in Ruby and Rails.

Note: Feel free to copy the examples into a Ruby console to see them in action.

Creating Hashes

There are multiple ways to create a Hash. Here are my favorites.

Create an empty hash

my_hash = {} # {}

Create a hash of values

my_hash = { 'First Name' => 'Steve', 'age' => 30, 'description' => 'human male' } 
# { "First Name" => "Steve", "age" => 30, "description" => "human male" }
Note: Notice how the integers remain integers

You can also use Array style syntax to create the hash

my_hash = Hash[ 'First Name', 'Steve', 'age', 30, 'description', 'human male' ]
# { "First Name" => "Steve", "age" => 30, "description" => "human male" }

If you use symbols for your hash keys, then you can create a hash using a shorter syntax.

my_hash = { first_name: 'Steve', age: 30, description: 'human male' } 
# { :first_name => "Steve", :age => 30, :description => "human male" }

Get details about the Hash

For the following examples, we are going to use the following my_hash

my_hash = { 'First Name' => 'Steve', 'age' => 30, 'description' => 'human male' } 

To access a value in the hash, just supply the key

my_hash['description'] # "human male"
my_hash['age'] # 30
my_hash['First Name'] # "Steve"

To access a value in the hash 'like a pro', you can use the fetch method.

my_hash.fetch('description') # "human male"
my_hash.fetch('color') # RAISES Exception -  KeyError: key not found: "color"
my_hash.fetch('color', 'key not found') # "key not found"
my_hash.fetch('color') {|key| "the #{key} key was not found" } # "the color key was not found"
Fetch gives you multiple ways of dealing with incorrect or missing key names

How long is the Hash?

my_hash.length # 3

Show each item in the Hash with key and value index

my_hash.each do |key, value|
  puts "#{key} is #{value}"
end
# First Name is Steve
# age is 30
# description is human male

Check to see if a Hash has a key

my_hash.has_key?('age') #true
my_hash.has_key?('size') #false

Searching the Hash

For the following examples, we are going to use the following my_hash:

my_hash = { 'First Name' => 'Steve', 'age' => 30, 'description' => 'human male' } 

Search the hash to see if a value exists within the hash, returns the key/value in an array or nil

my_hash.rassoc('Steve') # ["First Name", "Steve" ]
my_hash.rassoc('Simon') # nil
Note: This only works on the full entry, it can't do partial searches.

Search the hash using a block, returns a hash of matching items

my_hash.select {|a| a.include? 'st'} # {"First Name"=>"Steve"}
Note: The include? partial search works as it is done on the string and not the whole hash

Modify the Hash

For the following examples, we are going to use the following my_hash, you will need to recreate it before each example.

my_hash = { 'First Name' => 'Steve', 'age' => 30, 'description' => 'human male' } 

Add an new item to hash

my_hash['eyes'] = 'blue' # blue
# my_hash now becomes
# { 'First Name' => 'Steve', 'age' => 30, 'description' => 'human male', 'eyes' => 'blue'}

Merge 2 hashes together, values from the new hash will OVERWRITE existing values in the first hash

new_hash = { 'First Name' => 'Simon', 'hair' => 'blond'} 
my_hash.merge(new_hash)
# { 'First Name' => 'Simon', 'age' => 30, 'description' => 'human male', 'hair' => 'blond'}
my_hash.merge('First Name' => 'Stan')
# { 'First Name' => 'Stan', 'age' => 30, 'description' => 'human male'}
Note: Supports the ! character if you want to overwrite the existing hash

Merge 2 hashes and keep the existing values

new_hash = { 'First Name' => 'Simon', 'hair' => 'blond'} 
my_hash.merge(new_hash) { |key, value1, value2| value1 }
# { 'First Name' => 'Steve', 'age' => 30, 'description' => 'human male', 'hair' => 'blond'}

Note: This is just a simple block that returns the first hash value if it exists

Modify each item in the hash using a block, supports !

my_hash.map {|a| a.upcase} # ["START", "TWO", "3", "FOUR", "LAST_ENTRY"]
Remember that a method with ! means that the variable will be modified directly.

Rails specific Hash methods

Convert a hash to a URL Query String. Very handy when accessing API's

{ 'First Name' => 'Steve', 'age' => 30, 'description' => 'human male' }.to_param 
# "First+Name=Steve&age=30&description=human+male"

Convert a hash to XML

{ 'First Name' => 'Steve', 'age' => 30, 'description' => 'human male' }.to_xml 
# <?xml version=\"1.0\" encoding=\"UTF-8\"?>
# <hash>
#  <First-Name>Steve</First-Name>
#  <age type=\"integer\">30</age>
#  <description>human male</description>
# </hash>

Resources

Ruby Hash Class - The complete list of all Hash methods.

Rails Hash Class - The extra Hash methods you get when using Rails



comments powered by Disqus