cult3

Working with Hashes in Ruby

Apr 08, 2015

Table of contents:

  1. When would you use a Hash?
  2. Creating a new Hash
  3. Adding values to an existing hash
  4. Getting the value of a key
  5. Getting the key from a value
  6. Deleting a value
  7. Size, Length
  8. Iterating over a Hash
  9. Conclusion

Last week we looked at Arrays in Ruby. An Array is a useful data structure for working with a collection of items.

A Hash is a similar Ruby data structure in that it allows you to work with a collection of items. However, a Hash is a dictionary of keys and values, where unlike an Array, the key can be of any object type.

In today’s tutorial we’ll look at how to use Hashes in Ruby.

When would you use a Hash?

A Hash is a very useful data structure in Ruby for a number of reasons.

Firstly, when you want to pass around something of meaning that doesn’t warrant becoming a fully fledged class:

person = { first_name: 'Philip', last_name: 'Brown' }

We can now use the person hash in our Ruby code as a single object, but we didn’t need to create a Person class.

Hashes are also used as the argument to a method. When you pass a hash to method, you do not need to use the curly braces:

person = Person.create(first_name: 'Philip', last_name: 'Brown')

This makes it a really easy way to use named parameters.

Creating a new Hash

There are a couple of different ways to create a Hash in Ruby.

Firstly, you can use the implicit form:

friend1 = { 'name' => 'Chance', 'breed' => 'American Bulldog' }

Secondly, you can use symbols:

friend2 = { name: 'Shadow', breed: 'Golden Retriever' }

Alternatively you could write the above as:

friend2 = { name: 'Shadow', breed: 'Golden Retriever' }

Finally you can also call the new class method on Hash object:

friend3 = Hash.new
friend3['name'] = 'Sassy'
friend3['breed'] = 'Himalayan cat'

Adding values to an existing hash

To add a key and value pair to an existing hash, you can use square brackets:

list = {apples: 1, oranges: 2}
# => {:apples => 1, :oranges => 2}

list[:pears] = 3
# => 3

puts list
# => {:apples => 1, :oranges => 2, :pears => 3}

Alternatively you can use the store method:

list.store(:peaches, 4)
# => 4

puts list
# {:apples => 1, :oranges => 2, :pears => 3, :peaches => 4}

Getting the value of a key

There are a couple of ways to get a value from a key of a particular Hash.

The most used method you will see is by using square brackets:

movie = { title: 'The Lion King', date: 1994 }

movie[:title]
# => "The Lion King"

You can also call the fetch method:

movie.fetch(:title)
# => "The Lion King"

Getting the key from a value

If you would like to get the key of a particular value from a hash, you can call the key method:

people = { jack: 'twitter', zuck: 'Facebook', evan: 'snapchat' }

people.key('snapchat')
# => :evan

Deleting a value

If you want to delete a value from a Hash, you can call the delete method and pass the key of the value you want to delete:

results = { football: 56, tennis: 45, basketball: 23 }

results.delete(:basketball)

puts results
# => {:football => 56, :tennis => 45}

You can call the clear method to remove all of the keys and values from a Hash:

results.clear
# => {}

And you can check to see if a Hash is empty or not with the empty? method:

results.empty?
# => true

Size, Length

Its often very useful to determine the number of items in a hash. To do that you can use either the length or the size methods:

cities = { england: 'london', france: 'paris', germany: 'berlin' }

cities.length
# => 3

cities[:berlin] = 'Brussels'
# => "Brussels"

cities.size
# => 4

Iterating over a Hash

When you have many items in a hash, you will often want to iterate over the items and do something with each one.

There are a few methods that allow to do just that.

Firstly, there’s the each method that accepts a block. The block is called for each key in the hash and gets passed both the key and the value as parameters:

cities = {
  england: 'london',
  france: 'paris',
  germany: 'berlin',
  belgium: 'brussels'
}

cities.each { |key, value| puts "#{value} is a city in #{key}" }
# london is a city in england
# paris is a city in france
# berlin is a city in germany
# brussels is a city in belgium

If you want to filter a hash you can pass a block that evaluates each element of a block to only select items that return true.

scores = { jane: 98, toby: 67, mary: 89, jim: 54 }

scores.select { |key, value| value > 90 }
# => {:jane => 98}

Conclusion

The Hash object is something that you will see a lot of in Ruby. Hashes are very useful for passing around simple data objects where it’s useful to identity items in the collection with a key.

Hash objects are also commonly used as config options or passed as the argument of a method to use as named parameters.

Philip Brown

@philipbrown

© Yellow Flag Ltd 2024.