Hashes

The next class that we are going to look at is the Hash.

Hashes are a generalization of arrays. Instead of only permitting integer indices, as in array\[3], hashes allow any object to be used as an “index”. So, you can write hash["name"].

Suppose that I want to store some information about a friend. I could use an array, like this:

friend = [ "Jeffrey", "Biggs", "34 Airport Rd",  
      "Toronto", "Ontario" 
]

This could work, but I would have to remember that friend\[0] is the first name, friend\[1] is the last name and so on. It could get quite complicated.

This is exactly the kind of problem that a hash can help you with. This is how you define a hash:

friend = {
  "first name" => "Jeffrey",
  "last name"  => "Biggs",
  "address"    => "34 Airport Rd",  
  "city"       => "Toronto",
  "province"   => "Ontario"
}

Just like arrays, you can later add another field like this:

friend["country"] = "Canada"  

Notice that you create hashes using {squigly brackets} instead of the [square brackets] used for arrays.

Some terminology: keys and values

Since hashes don’t use numeric indices, we use the word keys instead. The objects that the keys refer to are called values.

So, in the above example, the keys are “first name”, “last name” and “city” are some of the keys. Their respective values are “Jeffrey”, “Biggs” and “Toronto”.

Iterating through hashes

Hashes also have iterators. They actually have a few.

Hash#each

Hashes have a Hash#each method, similar to Array#each. This method, however, supplies both the key and the value.

friend.each do |key, value| 
  puts key + " => " + value 
end

This produces:

city => Toronto
last name => Biggs
country => Canada
province => Ontario
address => 34 Airport Rd  
first name => Jeffrey

This points to one drawback of hashes. The data in a hash is not organized in any particular order. Is there any reason why Ruby should know that “first name” comes before “city”? Not at all.

The best way to deal with this sort of problem is by creating your own class which takes care of the problem. Ruby is an excellent language for creating your own classes. But before we do that, there is some material that we should cover. Creating classes and methods is the topic of the next chapter.

Hash#each_pair is a synonym for Hash#each.

Hash#each_key

The name says it all. This method iterates through all the keys just like Arrah#each.

>> friend.each_key do |key|  
?>     puts key
>> end
city
last name
country
province
address
first name

Hash#each_value

Iterates through all the values.

>> friend.each_value do |val|  
?>     puts val
>> end
Toronto
Biggs
Canada
Ontario
34 Airport Rd
Jeffrey

Exercises

A hash of movies: a short description here.

A hash of friends

A hash of celebrities

A hash of NUMBERS: given a hash of numbers, can you sort them?

 

Exercise:

Using hashes, make it print out 3 genres of movies and an example of a film for each.

 
 

Exercise idea: Using hashes create a record of five friends that includes their name, age, and hometown. Print out their names + “is from ” hometown + “and is ” age + “years old.”

 
 

Exercise:

Using hashes make it print out four people’s names and their celebrity look-alike next to them.

 
   

so for the hashes, even if you entered the values in order from name to providence it won’t be in order in the hash? i noticed that you put the name in first, so shouldn’t the name be the first value in the hash? why is the city the first value?