Altcademy - a Forbes magazine logo Best Coding Bootcamp 2023

What are Hashes in Ruby?

In this blog post, we will explore the concept of hashes in Ruby, a popular programming language known for its simplicity and elegance. Hashes are a powerful and versatile data structure that can make your code more efficient and organized. We will introduce you to what hashes are, how they work, and provide real-world examples to help you understand and implement them in your code.

What is a Hash?

A hash is a data structure, which is a way to store and organize data in a program. In Ruby, a hash is similar to an array, but instead of using numerical indexes to access the elements, it uses a unique key. The key can be any data type, such as a string, symbol, or number, and it points to a value. This makes hashes an ideal choice when you need to store and access data using meaningful labels or identifiers.

Imagine you have a list of students and their grades, and you want to store this information in a program. Using an array, you might store the data like this:

students = ["Alice", "Bob", "Charlie"]
grades = [90, 85, 95]

Although this method works, it can be cumbersome to access the data, especially as the list grows. You would need to know the index of a specific student to access their grade, and adding or removing students would require updating both arrays.

Now, let's store the same data using a hash:

grades = {
  "Alice" => 90,
  "Bob" => 85,
  "Charlie" => 95
}

With a hash, you can store the student's name as the key and their grade as the value. This makes it much easier to access and update the data. For example, you can quickly look up a grade by the student's name, like this:

puts grades["Alice"]

This would output 90, the grade for Alice.

Creating a Hash

There are several ways to create a hash in Ruby. The most common method is to use the hash literal syntax, which is curly braces {} with key-value pairs separated by commas. Each key is separated from its corresponding value by a rocket =>. Here's an example:

person = {
  "name" => "John",
  "age" => 30,
  "city" => "New York"
}

You can also create an empty hash by using the Hash.new method:

empty_hash = Hash.new

Another way to create a hash is to use the Hash[] method, which takes an even number of arguments and pairs them as keys and values:

colors = Hash["red", 1, "blue", 2, "green", 3]

This will create a hash with the following key-value pairs:

{
  "red" => 1,
  "blue" => 2,
  "green" => 3
}

Accessing and Modifying Hashes

You can access and modify the values in a hash using the keys. To access a value, use the key inside square brackets []:

puts person["name"] # Output: John

To modify a value, simply assign a new value to the key:

person["age"] = 31
puts person["age"] # Output: 31

To add a new key-value pair to the hash, use the same syntax:

person["job"] = "Developer"
puts person["job"] # Output: Developer

If you try to access a key that does not exist in the hash, Ruby will return nil:

puts person["country"] # Output: nil

You can use the fetch method to access a key's value and provide a default value if the key does not exist:

puts person.fetch("country", "USA") # Output: USA

Iterating Over a Hash

You can use the each method to iterate over the key-value pairs in a hash. The each method takes a block, which is a piece of code enclosed by do and end or curly braces {}. The block receives the key and value as arguments, and you can perform operations on them.

Here's an example that prints the keys and values of a hash:

person.each do |key, value|
  puts "#{key}: #{value}"
end

This would output:

name: John
age: 31
city: New York
job: Developer

You can also use the each_key and each_value methods to iterate over just the keys or values, respectively:

person.each_key do |key|
  puts "Key: #{key}"
end

person.each_value do |value|
  puts "Value: #{value}"
end

Deleting Items from a Hash

To delete an item from a hash, use the delete method and pass the key as an argument:

person.delete("job")
puts person["job"] # Output: nil

If the key does not exist, the delete method returns nil. You can provide a block to the delete method that will be executed when the key is not found:

person.delete("country") { "Not found" } # Output: Not found

Symbols as Keys

In many cases, you'll see hashes in Ruby using symbols as keys instead of strings. Symbols are similar to strings, but they are more efficient in terms of memory and performance. Symbols are created using a colon : followed by the symbol name:

person = {
  :name => "John",
  :age => 30,
  :city => "New York"
}

You can also use the new syntax introduced in Ruby 1.9, which makes the hash definition cleaner:

person = {
  name: "John",
  age: 30,
  city: "New York"
}

This new syntax is equivalent to the previous one, and the keys are still symbols. Accessing and modifying the hash remains the same:

puts person[:name] # Output: John

person[:age] = 31
puts person[:age] # Output: 31

Conclusion

Hashes are a powerful and flexible data structure in Ruby that can greatly improve the way you store and access data in your programs. By understanding and using hashes, you can write more efficient and organized code, making your life as a developer much easier.

In this blog post, we covered the basics of hashes, including creating, accessing, modifying, iterating, and deleting items. We also discussed the use of symbols as keys. With this foundation, you can now confidently implement hashes in your Ruby projects and harness their full potential.