DEV Community

Cover image for Hashes in Ruby
Augusto Kato
Augusto Kato

Posted on

Hashes in Ruby

Ruby hashes are similar to objects in JS, or Dictionaries in Python.

Hashes are like dining menus, the dish names are the keys and the food are the values.

Creating Hashes

Using literal ({}):

my_hash = {
  "a random word" => "pineapple",
  "Amanda's math test score" => 94,
  "an array" => [1, 2, 3],
  "an empty hash within a hash" => {}
}
Enter fullscreen mode Exit fullscreen mode

Using ::new:

my_hash = Hash.new
my_hash               #=> {}
Enter fullscreen mode Exit fullscreen mode

Accessing Values

It's the same way that you access elements in an array.

movies = {
  "horror" => "Talk To Me",
  "action" => "Blue Beetle"
}

movies["horror"]   #=> "Talk To Me"
Enter fullscreen mode Exit fullscreen mode

Adding or Changing Data

Just call the key and set a value:

movies["drama"] = "Eternal Sunshine Of The Spotless Mind"

movies     #=> {"horror" => "Talk To Me", "action" => "Blue Beetle", "drama" => "Eternal Sunshine Of The Spotless Mind"}
Enter fullscreen mode Exit fullscreen mode
movies["horror"] = "Scream"
movies     #=> {"horror" => "Scream", "action" => "Blue Beetle", "drama" => "Eternal Sunshine Of The Spotless Mind"}
Enter fullscreen mode Exit fullscreen mode

Removing Data

Use #delete method, and it returns the value of the key-value pair that was deleted from the hash:

movies.delete("horror")    #=> "Scream"
movies                     #=> {"action" => "Blue Beetle", "drama" => "Eternal Sunshine Of The Spotless Mind"}
Enter fullscreen mode Exit fullscreen mode

Methods

Specific to hashes: #keys and #values

movies = {
  "The Grand Budapest Hotel" => "Wes Anderson",
  "Lost in Translation" => "Sofia Coppola",
  "Lady Bird" => "Greta Gerwig"
}


movies.keys      #=> ["The Grand Budapest Hotel", "Lost in Translation", "Lady Bird"]
movies.values    #=> ["Wes Anderson", "Sofia Coppola", "Greta Gerwig"]
Enter fullscreen mode Exit fullscreen mode

Merging two hashes

The hash2 will overwrite the values of hash1:

hash1 = { "a" => 100, "b" => 200 }
hash2 = { "b" => 254, "c" => 300 }
hash1.merge(hash2)      #=> { "a" => 100, "b" => 254, "c" => 300 }
Enter fullscreen mode Exit fullscreen mode

Symbols as Hash Keys

Symbols are used as keys because they are more performant than strings:

# 'Rocket' syntax
american_cars = {
  :chevrolet => "Corvette",
  :ford => "Mustang",
  :dodge => "Ram"
}
# 'Symbols' syntax
japanese_cars = {
  toyota: "Supra",
  mazda: "RX-7",
  subaru: "Impreza"
}
Enter fullscreen mode Exit fullscreen mode

To access:

american_cars[:ford]    #=> "Mustang"
japanese_cars[:mazda]   #=> "RX-7"
Enter fullscreen mode Exit fullscreen mode

Common Hash Methods

key?

The key? method allows you to check if a hash contains a specific key. It returns a boolean value.

irb :001 > name_and_age = { "Bob" => 42, "Steve" => 31, "Joe" => 19}
=> {"Bob"=>42, "Steve"=>31, "Joe"=>19}
irb :002 > name_and_age.key?("Steve")
=> true
irb :003 > name_and_age.key?("Larry")
=> false
Enter fullscreen mode Exit fullscreen mode

select

The select method allows you to pass a block and will return any key-value pairs that evaluate to true when passed to the block.

irb :004 > name_and_age.select { |k,v| k == "Bob" }
=> {"Bob"=>42}
irb :005 > name_and_age.select { |k,v| (k == "Bob") || (v == 19) }
=> {"Bob"=>42, "Joe"=>19}
Enter fullscreen mode Exit fullscreen mode

fetch

The fetch method allows you to pass a given key and it will return the value for that key if it exists. You can also specify an option for return if that key is not present.

irb :006 > name_and_age.fetch("Steve")
=> 31
irb :007 > name_and_age.fetch("Larry")
=> KeyError: key not found: "Larry"
     from (irb):32:in `fetch'
     from (irb):32
     from /usr/local/rvm/rubies/ruby-2.5.3/bin/irb:16:in `<main>'
irb :008 > name_and_age.fetch("Larry", "Larry isn't in this hash")
=> "Larry isn't in this hash"
Enter fullscreen mode Exit fullscreen mode

to_a

The to_a method returns an array version of your hash when called.

irb :009 > name_and_age.to_a
=> [["Bob", 42], ["Steve", 31], ["Joe", 19]]
irb :010 > name_and_age
=> {"Bob"=>42, "Steve"=>31, "Joe"=>19}
Enter fullscreen mode Exit fullscreen mode

Top comments (1)

Collapse
 
cherryramatis profile image
Cherry Ramatis

Great content cousin!