Heather_TN
Heather_TN

Reputation: 31

How to loop nested arrays in Ruby

VERY new to Ruby and coding in general. I'm trying to loop through two dimensional arrays but can't figure it out. Here's what I have:

--Use a loop to print out each person on separate lines with their alter egos.

--Bruce Wayne, a.k.a. Batman

people = [
  ["Bruce", "Wayne", "Batman"],
  ["Selina", "Kyle", "Catwoman"],
  ["Barbara", "Gordon", "Oracle"],
  ["Terry", "McGinnis", "Batman Beyond"]
]

index = people[0][0]

first_name = people[0][0]
last_name = people[0][1]
hero_name = people[0][2]

4.times do
  puts first_name + " " + last_name + "," " " + "a.k.a" " " + hero_name
  index = index + 1
end

It does print the first line but then raises an error:

Bruce Wayne, a.k.a Batman
# `+': no implicit conversion of Integer into String (TypeError)

Upvotes: 3

Views: 3338

Answers (3)

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121000

In ruby we don’t use loops by index, like for and family; instead we iterate on collections:

people =
  [["Bruce", "Wayne", "Batman"],
   ["Selina", "Kyle", "Catwoman"],
   ["Barbara", "Gordon", "Oracle"],
   ["Terry", "McGinnis", "Batman Beyond"]]

people.each do |first, last, nick|
  puts "#{first} #{last}, a.k.a #{nick}"
end

or

people.each do |first_last_nick|
  *first_last, nick = first_last_nick
  puts [first_last.join(' '), nick].join(', a.k.a ')
end

Upvotes: 7

iGian
iGian

Reputation: 11193

For your code to work:

4.times do |character|
  puts people[character][0] + " " + people[character][1] + "," " " + "a.k.a" " " + people[character][2]
end 

But iterating in ruby is done as answered by others. This is a version using a block {} instead:

people = [["Bruce", "Wayne", "Batman"], ["Selina", "Kyle", "Catwoman"], ["Barbara", "Gordon", "Oracle"], ["Terry", "McGinnis", "Batman Beyond"]]

people.each { |character| puts "#{character [0]}, a.k.a   #{character [1]} #{character [2]}" }

#=> Bruce, a.k.a   Wayne Batman
#=> Selina, a.k.a   Kyle Catwoman
#=> Barbara, a.k.a   Gordon Oracle
#=> Terry, a.k.a   McGinnis Batman Beyond

In general to loop through nested arrays:

people.each do |character|
  character.each do |name|
    puts name
  end
end

Upvotes: 0

peter
peter

Reputation: 42192

Your code produces error because you assign a String to index

index = people[0][0]

and then you use it to count with

index = index + 1

You could have used

index = 0 

and

index += 1 

A more Rubyesque way would be to enumerate the array and print it like this

people.each do |person|
  puts "#{person.first} #{person[1]}, a.k.a #{person.last}"
end

Which gives

Bruce Wayne, a.k.a Batman
Selina Kyle, a.k.a Catwoman
Barbara Gordon, a.k.a Oracle
Terry McGinnis, a.k.a Batman Beyond

Storing the parts in a variable improves readability but lenghtens the code which in turn diminishes readability, the choice is yours..

As an alternative you could name the indices or decompose like mudasobwa suggests.

Firstname, Lastname, Nickname = 0, 1, 2
people.each do |person|
  puts "#{person[Firstname]} #{person[Lastname]}, a.k.a #{person[Nickname]}"
end

Upvotes: 2

Related Questions