рубиновый хэш ищет два критерия - PullRequest
0 голосов
/ 25 февраля 2019
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}
]

Я пытаюсь получить учащегося с самым высоким показателем, которому 20 лет, но он может отсортировать только самое высокое по всем учащимся.Кто-нибудь знает, как ограничить max_by только для студентов, которым 20 из вышеуказанного хеша?

Ответы [ 3 ]

0 голосов
/ 25 февраля 2019

Моя цель состоит в том, чтобы сделать один проход через хэши.

Первоначально я опубликовал следующее, но оно было неверным, поскольку оно возвращает имя студента, которому не исполнилось 20 лет, если нет учеников возраста20.

grades.max { |h| h[:age] == 20 ? h[:score] :
  -Float::INFINITY }[:student]

Вот мой исправленный ответ:

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
0 голосов
/ 25 февраля 2019

Точно так же, как идея.

Предположим, у нас несколько учеников 20-летнего возраста с одинаковым максимальным баллом.

В этом случае варианты Cary и Ursus возвращают только первое лицо.

Поэтому мне пришла в голову такая мысль:

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

Не судите строго, это всего лишь идея.

0 голосов
/ 25 февраля 2019
  1. фильтр для людей с возрастом 20
  2. найти максимальный балл

    grades.select { |person| person[:age] == 20 }.max_by { |person| person[:score] }
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...