Arrays are useful for a list of similar types of things, or a random assortment of things. But sometimes, we have very different things that need to be more explicitly identified. For example, our favorite_foods
array held multiple foods. But what if we wanted to represent all our favorite things in code? An array would be a little confusing:
favorite_things = ["Purple", 17, "Apple"]
Looking at that list, we don't know what the elements are. Is "Apple" a favorite fruit, computer, or company? Is "Purple" a favorite color or a favorite set of sheets? With this type of data, it would be helpful to identify each element more clearly. To do so, we use a Hash (known as a Dictionary in some languages).
A hash is a list of key-value pairs. Here is the same data from before, but using a hash:
favorite_things = { "color" => "purple", "number" => 17, "computer" => "Apple" }
Notice how we use curly braces { }
to enclose the list of items, and we use commas to separate each item. The "key" => value
pair can be written this way with a string as the key and a fat arrow or hash rocket operator (=>
) . You may also see it represented as this:
favorite_things = { :color => "purple", :number => 17, :computer => "Apple" }
or this:
favorite_things = { color: "purple", number: 17, computer: "Apple" }
All versions are acceptable, but we'll use the first format.
To see another example of a hash, let's model a user's profile data as a hash:
let user = {
"name" => "Ben",
"location" => "Chicago, IL",
"status" => "Staying warm!"
}
Similar to an array, the values within a hash can be anything, even other hashes or arrays. Let's flesh out the location data:
let user = {
"name" => "Ben",
"location" => { "city" => "Chicago", "state" => "IL" },
"status" => "Staying warm!"
}
Accessing Elements within Hashes
Unlike an array, the order of a hash doesn't matter. We never care about the first thing in a hash - we want to know the value of a key in the hash. For example, if we want to get the user's name, we use square brackets [ ]
around the key:
name = user["name"]
puts name
To access values in a nested hash, we chain the keys together:
city = user["location"]["city"]
puts city
state = user["location"]["state"]
puts state
Modifying Hashes
Data is rarely static - it's frequently changing. We can modify our hash by assigning a new value to a key:
user["status"] = "Writing some code."
puts user
user["location"]["city"] = "Evanston"
puts user
Hashes and Arrays
By combining hashes and arrays, we can pretty much represent any real-world data. Let's see them together:
let user = {
"name" => { "first" => "Ben", "last" => "Block" },
"location" => { "city" => "Chicago", "state" => "IL" },
"timeline" => [{ "status" => "Brrr!", "posted_at" => "9:00am" },
{ "status" => "Coding.", "posted_at" => "10:00am" },
{ "status" => "Lunch time.", "posted_at" => "12:00pm" }]
}
It takes a bit of digging to get to the data you want in these more complex objects:
let first_name = user["name"]["first"]
let first_status = user["timeline"][0]["status"]
puts "#{first_name}'s first post was #{first_status}"
Lab
Time for a lab to practice working with hashes. Instructions are in the file 4-hashes.rb
in the labs
directory.