Learn Ruby - Iteration Nested Data Structures

Question Click to View Answer

What does the following code return?


:id is an instance of the Symbol class (it is a symbol object that was created by the Symbol class).

result = []
weird_array = ["blah", :meow, 42, 90, :building]

Iterate over every element of weird_array and add the element to the result array if the element is a Symbol (i.e. an instance of the Symbol class).

weird_array.each do |element|
  if element.instance_of?(Symbol)
sports = ["basketball", "baseball", "football"]

Iterate over the sports Array and print out the following list:

"0. basketball"
"1. baseball"
"2. football"
sports.each_with_index do |sport, index|
  puts index.to_s + ". " + sport

The each_with_index() method keeps track of the index of each element in the array (remember, Array's are zero-indexed, meaning that the first element corresponds to 0). Sport and index are called block variables and we can name them however we want, but it best to use a variable name that makes sense. Notice that two block variables are required with the each_with_index() method - one to keep track of the element and another to keep track of the index. To prove that the block variables can be named anything, please run the following example:

sports.each_with_index do |cat, shirt|
  puts shirt.to_s + ". " + cat
last_names = ["D", "Krugman"]

Iterate over last_names and create this array: ["Paul D", "Paul Krugman"]

last_names.map do |last_name|
  "Paul " + last_name

The map() method is used to create a new array.

soap_opera = ["all", "my", "children"]

Return true if any of the elements in the soap_opera array start with the letter "a" and false otherwise.

soap_opera.any? do |word|
  word[0] == "a"

The any?() method iterates over every element of the array and returns true if the code block is ever true. Methods with question marks in Ruby return true or false and are called predicate methods.

tools = ["ruby", "rspec", "rails"]

Return true if every element of the tools array starts with an "r" and false otherwise.

tools.all? do |tool|
  tool[0] == "r"

The all?() method iterates over every element of the array and returns true if the code block is always true.

Return true if the string "stimpy" contains the letter "s" and false otherwise.

captain_planet = ["earth", "fire", "wind", "water", "heart"]

Create a new array from the captain_planet array with all the elements that contain the letter "a".

captain_planet.select do |word|
stuff = ["candy", :pepper, "wall", :ball, "wacky"]

Identify the first element in the stuff array that begins with the letters "wa".

stuff.find do |word|
  word[0..1] == "wa"
stuff = ["candy", :pepper, "wall", :ball, "wacky"]

Identify all the elements in the stuff array that begins with the letters "wa".

stuff.find_all do |word|
  word[0..1] == "wa"

# OR

stuff.select do |word|
  word[0..1] == "wa"
abcs = [:a, :b, :c]

Create the array [:c, :b, :a] from the abcs array.

people = [["Lebron", "cool dude"], ["Bieber", "jerk face"]]

The people array is an array of two arrays (this is also called a nested array).

Get the first element of the people array.


The first element of the people Array is ["Lebron", "cool dude"].

people = [["Lebron", "cool dude"], ["Bieber", "jerk face"]]

Get the "cool dude" string from the people array.


people[0] is the same as ["Lebron", "cool dude"], so the expression simplifies to ["Lebron", "cool dude"][1], which equals "cool dude".

x = "cat"
y = "hat"

Show two ways to concatenate x and y to form the sentence: "the cat and the hat"

"the " + x + " and the " + y
"the #{x} and the #{y}"

The second method is called string interpolation and many programmers consider this technique more readable.

people = [["Lebron", "cool dude"], ["Bieber", "jerk face"]]

Iterate through the people array and print the following sentences: Lebron is a cool dude Bieber is a jerk face

people.each do |first_name, description|
  puts "#{first_name} is a #{description}"

# OR (the significantly less readable answer):

people.each do |person|
  puts "#{person[0]} is a #{person[1]}"
test_scores = [["jon", 99], ["sally", 65], ["bill", 85]]

Create an array of all students with test scores greater than 80. The result should be [["jon", 99], ["bill", 85]].

test_scores.select do |name, score|
  score > 80
ages = [[:frank, 42], [:sue, 77], [:granny, 77]]

Get the first person from the ages array that is 77 years old. The result should be [:sue, 77]

ages.find do |name, age|
  age == 77
planets = {:earth => [:luna], :mars => [:deimos, :phobos], :jupiter => [:callisto, :io, :europa]}

Return the moons of :mars.

planets = {:earth => [:luna], :mars => [:deimos, :phobos], :jupiter => [:callisto, :io, :europa]}

Return the moons of :mars as a single string separated by a comma. Result should be "deimos, phobos".

planets[:mars].join(", ")
baseball_players = {:babe_ruth => {:hits => 2873, :home_runs => 714, :obp => 474}, :barry_bonds => {:hits => 2935, :home_runs => 762, :obp => 444}}

Return the number of home_runs that Babe Ruth hit in his career.


Nested hashes produce readable code. From the above line, it is easy to determine that we are getting the number of home runs for Babe Ruth.

baseball_players_array = [[:babe_ruth, [2873, 714, 474]], [:barry_bonds, [2935, 762, 444]]]

The baseball_players_array has the same information as the hash in the previous questions. Return the number of home runs that Babe Ruth hit in his career. Result should be 714.


This is significantly less readable than the nested hash.

economists = [{:name => "krugman", :specialty => "international macro"}, {:name => "mankiw", :specialty => "pigovian taxation"}]

Describe the data structure of the economists variable. Get the name of the first element in the economists array (result should be "krugman").


economists is an array of hashes.