Reputation: 19
grades = [
{:student=>"James", :age=>19, :score=>85},
{:student=>"Kate", :age=>19, :score=>92},
{:student=>"Sara", :age=>20, :score=>74},
{:student=>"Riley", :age=>20, :score=>85},
{:student=>"patrick", :age=>20, :score=>96},
{:student=>"luke", :age=>21, :score=>88},
{:student=>"susie", :age=>21, :score=>90}
]
I am trying to get the student with the highest score that is the age 20 but only can sort the highest by all the students. Does any one know how to limit the max_by to only students that are 20 from the above hash ?
Upvotes: 1
Views: 62
Reputation: 15298
Just as idea.
Suppose we have several 20-year-old students with the same maximum score.
In this case variants of Cary and Ursus return only first person.
Therefore, such a thought occurred to me:
grades = [
{:student=>"James", :age=>19, :score=>85},
{:student=>"Kate", :age=>19, :score=>92},
{:student=>"Sara", :age=>20, :score=>74},
{:student=>"Riley", :age=>20, :score=>85},
{:student=>"Patrick", :age=>20, :score=>96},
{:student=>"Vladimir", :age=>20, :score=>96},
{:student=>"Luke", :age=>21, :score=>88},
{:student=>"Susie", :age=>21, :score=>90}
]
def best20(grades)
students20 = grades.select { |r| r[:age] == 20 }
return nil if students20.empty?
max_score20 = students20.max_by { |r| r[:score] }[:score]
students20.select { |r| r[:score] == max_score20 }.map { |r| r[:student] }
end
best20 grades
# => ["Patrick", "Vladimir"]
best20 [{:student=>"James", :age=>19, :score=>85}]
# => nil
Do not judge strictly, this is just an idea.
Upvotes: 0
Reputation: 110725
My objective is to make a single pass through the hashes.
Initially I posted the following, but it was incorrect because it returns the name of a student who is not 20 if there are no students of age 20.
grades.max { |h| h[:age] == 20 ? h[:score] :
-Float::INFINITY }[:student]
Here is my revised answer:
def best20(grades)
student = nil
highest = -Float::INFINITY
grades.each do |h|
if h[:age] == 20 && h[:score] > highest
highest = h[:score]
student = h[:student]
end
end
student
end
best20 grades
#=> "patrick"
best20 [{:student=>"James", :age=>19, :score=>85}]
#=> nil
Upvotes: 1
Reputation: 30071
find the maximum score
grades.select { |person| person[:age] == 20 }.max_by { |person| person[:score] }
Upvotes: 4