A brief intro to Ruby arrays and hashes

Arrays and hashes are the two most common way to handle collections of objects in Ruby. Collections (which are objects themselves) not only help to organize our individual objects, they also have some powerful methods for iterating through or transforming all of the objects within them.

Imagine we are in charge of maintaining some record of a handful of individual objects, like all of the employees in a local restaurant: Bob, Linda, Tina, Gene, and Louise. We could define individual objects representing each employee, but by organizing them into a larger collection, we can make our life a little easier. Let’s start with arrays.

##Arrays

Arrays are ordered collections, or lists, of objects. This means that the objects in an array have a consistent ordering, and we can refer to objects in the array according to an index. Here’s a two ways to collect the employees’ names into a new array:

# Literal array constructor
employees = ["Bob", "Linda", "Tina", "Gene", "Louise"]
# %w array constructor
employees = %w{Bob Linda Tina Gene Louise}

Both methods yield the same resulting object, an array named employees with five string elements. Because arrays are ordered collections, we can use indexing to check out any element (or group of elements) in employees, like so:

employees[0] # => "Bob"
employees[1] # => "Linda"
employees[-1] # => "Louise"

We can also use Enumerable methods like #each to iterate through the array and make a change. Since all of these employees share the same last name, let’s add it to each element:

employees[0] # => "Bob"
employees.each do |name|
	name << " Belcher"
end

employees[2] # => "Tina Belcher"
employees[3] # => "Gene Belcher"

Names are important, but we’d probably want to keep track of other information, too, like each employee’s job titles. To do this, we could create a second array just for job titles:

job_titles = ["owner", "manager", "cook", "entertainer", "entertainer"]

puts employees[0] + " is an " + job_titles[0]
# => Bob Belcher is an owner

puts employees[3] + " is an " + job_titles[3]
# => Gene Belcher is an entertainer

The elements in job_titles follow the same order as the names in employees, so we can use the same index on each array to retrieve information. Of course, this assumes that both arrays were ordered properly, and that they won’t change. This could become difficult to manage in the long run, so it’s a good place to introduce a second kind of collection: hashes.

##Hashes

Like arrays, hashes are ordered collections of objects, too, but the elements within hashes are more complex. Each element in a hash is actually a pair of objects—a key and a value, or a key-value pair. Keys are unique identifiers of each element (just like names), while values are not (just like our job titles!). Here’s one way to create a hash called roster that stores employee names (the keys) and their corresponding job title (the values):

roster = { "Bob" 	=> "owner",
	   "Linda"	=> "manager",
	   "Tina"	=> "cook",
	   "Gene"	=> "entertainer",
	   "Louise"	=> "entertainer" }

Just like we did with an array, we could use an index to retrieve information from within each element, but we have to use #keys or #values to specify which piece of information we want.

roster.keys(0) # => "Bob"
roster.values(0) # => "owner"

A benefit of using a hash here is that the names are consistently with the job title within each element. We can also inspect parts of the hash according to the keys or values. Imagine we wanted to know just who the entertainers in this restuarant were:

roster.select{|key, value| value == "entertainer"}
# {
#		  "Gene" => "entertainer"
#		"Louise" => "entertainer"
# }

Or we could turn the question around, and ask what exactly it is that Tina does in the restaurant:

puts roster["Tina"] # => cook

##Arrays or hashes?

Of course, it depends! There’s a lot more to arrays and hashes than what I’ve shown here, and choosing the right one depends on the situation. To make things even crazier, both collections can be nested—we could have arrays within arrays, hashes within arrays, hashes within hashes, and arrays within hashes!

I’ve barely scratched the surface here, so you’ll want to check out some other resources to get a better handle on these collections (or just wait until I finish my Ruby collection manifesto). Here’s a few to get started with:

Happy collecting!