Arrays and hashes can be nested to model records with related details.

nested collection A nested collection stores one collection inside another, such as hashes inside an array.

Nested Collections

student_name
nested_collections.rb
Replay: real traced execution (multi-file project)
students = [
  { name: "Ada", scores: [8, 9] },
  { name: "Grace", scores: [10, 10] },
  { name: "Linus", scores: [7, 8] }
]
student_name = "Ada"

student = students.find do |entry|
  entry[:name] == student_name
end

if student
  total = student[:scores].sum
  average = total / student[:scores].length
  puts "student=#{student_name}"
  puts "total=#{total}"
  puts "average=#{average}"
else
  puts "student=#{student_name}"
  puts "status=missing"
end
students = [
  { name: "Ada", scores: [8, 9] },
  { name: "Grace", scores: [10, 10] },
  { name: "Linus", scores: [7, 8] }
]
student_name = "Grace"

student = students.find do |entry|
  entry[:name] == student_name
end

if student
  total = student[:scores].sum
  average = total / student[:scores].length
  puts "student=#{student_name}"
  puts "total=#{total}"
  puts "average=#{average}"
else
  puts "student=#{student_name}"
  puts "status=missing"
end
students = [
  { name: "Ada", scores: [8, 9] },
  { name: "Grace", scores: [10, 10] },
  { name: "Linus", scores: [7, 8] }
]
student_name = "Matz"

student = students.find do |entry|
  entry[:name] == student_name
end

if student
  total = student[:scores].sum
  average = total / student[:scores].length
  puts "student=#{student_name}"
  puts "total=#{total}"
  puts "average=#{average}"
else
  puts "student=#{student_name}"
  puts "status=missing"
end
  1. students ← [{:name=>"Ada", :scores=>[8, 9]}, {:name=>"Grace", :scores=>[10, 10]}, {:name=>"Linus", :scores=>[7, 8]}]

    1students→ [{:name=>"Ada", :scores=>[8, 9]}, {:name=>"Grace", :scores=>[10, 10]}, {:name=>"Linus", :scores=>[7, 8]}] = [2  { name: "Ada", scores: [8, 9] },3  { name: "Grace", scores: [10, 10] },4  { name: "Linus", scores: [7, 8] }5]6student_name→ Ada = "Ada"  #@student_name="Grace", "Matz"78student = students[{:name=>"Ada", :scores=>[8, 9]}, {:name=>"Grace", :scores=>[10, 10]}, {:name=>"Linus", :scores=>[7, 8]}].find do |entry|9  entry[:name] == student_name10end
  2. student ← {:name=>"Ada", :scores=>[8, 9]}

    8student→ {:name=>"Ada", :scores=>[8, 9]} = students[{:name=>"Ada", :scores=>[8, 9]}, {:name=>"Grace", :scores=>[10, 10]}, {:name=>"Linus", :scores=>[7, 8]}].find do |entry{:name=>"Ada", :scores=>[8, 9]}|9  entry[:name] == student_name10end
  3. total ← 17, average ← 8

    12if student{:name=>"Ada", :scores=>[8, 9]}13  total→ 17 = student[:scores].sum1714  average→ 8 = total17 / student[:scores].length215  puts "student=#{student_nameAda}"16  puts "total=#{total17}"17  puts "average=#{average8}"18else
    outputstudent=Ada
    total=17
    average=8
  1. students ← [{:name=>"Ada", :scores=>[8, 9]}, {:name=>"Grace", :scores=>[10, 10]}, {:name=>"Linus", :scores=>[7, 8]}]

    1students→ [{:name=>"Ada", :scores=>[8, 9]}, {:name=>"Grace", :scores=>[10, 10]}, {:name=>"Linus", :scores=>[7, 8]}] = [2  { name: "Ada", scores: [8, 9] },3  { name: "Grace", scores: [10, 10] },4  { name: "Linus", scores: [7, 8] }5]6student_name→ Grace = "Grace"78student = students[{:name=>"Ada", :scores=>[8, 9]}, {:name=>"Grace", :scores=>[10, 10]}, {:name=>"Linus", :scores=>[7, 8]}].find do |entry|9  entry[:name] == student_name10end
  2. do |entry|

    pass 1 of 2
    8student = students.find do |entry{:name=>"Ada", :scores=>[8, 9]}|9  entry[:name] == student_name10end
  3. student ← {:name=>"Grace", :scores=>[10, 10]}

    pass 2 of 2
    8student→ {:name=>"Grace", :scores=>[10, 10]} = students[{:name=>"Ada", :scores=>[8, 9]}, {:name=>"Grace", :scores=>[10, 10]}, {:name=>"Linus", :scores=>[7, 8]}].find do |entry{:name=>"Grace", :scores=>[10, 10]}|9  entry[:name] == student_name10end
  4. total ← 20, average ← 10

    12if student{:name=>"Grace", :scores=>[10, 10]}13  total→ 20 = student[:scores].sum2014  average→ 10 = total20 / student[:scores].length215  puts "student=#{student_nameGrace}"16  puts "total=#{total20}"17  puts "average=#{average10}"18else
    outputstudent=Grace
    total=20
    average=10
  1. students ← [{:name=>"Ada", :scores=>[8, 9]}, {:name=>"Grace", :scores=>[10, 10]}, {:name=>"Linus", :scores=>[7, 8]}]

    1students→ [{:name=>"Ada", :scores=>[8, 9]}, {:name=>"Grace", :scores=>[10, 10]}, {:name=>"Linus", :scores=>[7, 8]}] = [2  { name: "Ada", scores: [8, 9] },3  { name: "Grace", scores: [10, 10] },4  { name: "Linus", scores: [7, 8] }5]6student_name→ Matz = "Matz"78student = students[{:name=>"Ada", :scores=>[8, 9]}, {:name=>"Grace", :scores=>[10, 10]}, {:name=>"Linus", :scores=>[7, 8]}].find do |entry|9  entry[:name] == student_name10end
  2. do |entry|

    pass 1 of 3
    8student = students.find do |entry{:name=>"Ada", :scores=>[8, 9]}|9  entry[:name] == student_name10end
    All 3 passes — pass 1 is the card above
    passentrystudentsstudent_namestudent
    1{:name=>"Ada", :scores=>[8, 9]}
    2{:name=>"Grace", :scores=>[10, 10]}
    3{:name=>"Linus", :scores=>[7, 8]}[{:name=>"Ada", :scores=>[8, 9]}, {:name=>"Grace", :scores=>[10, 10]}, {:name=>"Linus", :scores=>[7, 8]}]Matz(empty)
  3. else

    17  puts "average=#{average}"18else19  puts "student=#{student_nameMatz}"20  puts "status=missing"21end
    outputstudent=Matz
    status=missing