Ruby — сортировка хэшей в порядке убывания по значению

#ruby #sorting #hash

#ruby #сортировка #хэш

Вопрос:

Я пытаюсь решить следующее:

«Вам предоставляется словарь / хэш / объект, содержащий несколько языков, и результаты вашего теста на заданных языках. Верните список языков, на которых ваш тестовый балл составляет не менее 60, в порядке убывания результатов.

Примеры: {«Java» => 10, «Ruby» => 80, «Python» => 65} —> [«Ruby», «Python»]

{«Хинди» => 60, «Голландский» => 93, «Греческий» => 71} —> [«Голландский», «греческий», «хинди»]

{«C » => 50, «ASM» => 10, «Haskell» => 20} —> []

У меня возникли проблемы с сортировкой в порядке убывания по результатам. Вот что у меня есть на данный момент

 def my_languages(results)
array = []
results.each { |a,b| 
results.values.sort.reverse
if b.to_i >= 60
array << a
end
}
return array
end
  

Не самое элегантное решение, но я полный новичок в Ruby (и в Stack Overflow тоже новичок — извините!) Любой совет был бы высоко оценен!

Ответ №1:

Вы как бы смешиваете этапы сортировки и фильтрации. Мое решение

  1. Фильтруйте результаты с помощью value >= 60
  2. Сортировка по значениям (по убыванию, -v )
  3. Извлеките первый элемент для каждого массива (название языка)

     def my_languages(results)
      results.select { |k, v| v >= 60 }.sort_by { |(k,v)| -v }.map(amp;:first)
    end
      

Комментарии:

1. С удовольствием 🙂 попробуйте вызывать метод по очереди и посмотрите, что возвращает

2. @jordantomiko прими этот ответ, если он ответит на твой вопрос. В левом верхнем углу есть пустая галочка, на которую вам нужно нажать, чтобы принять ответ.

Ответ №2:

 h = { "Java" => 10, "Ruby" => 80, "Python" => 65 }

h.select { |_,v| v >= 60 }.
  keys.
  sort_by { |k| -h[k] }
  #=> ["Ruby", "Python"] 
  

Шаги следующие.

 g = h.select { |_,v| v >= 60 }
  #=> {"Ruby"=>80, "Python"=>65} 
a = g.keys
  #=> ["Ruby", "Python"] 
a.sort_by { |k| -h[k] }
  #=> ["Ruby", "Python"] 
  

Если вас не волнуют -h[k] два альтернативных варианта, следуйте.

 h.select { |_,v| v >= 60 }.
  keys.
  sort_by { |k| h[k] }.
  reverse
  

и

 a = h.select { |_,v| v >= 60 }.
      keys
a.max_by(a.size) { |k| h[k] }
  

Я сомневаюсь, что можно было бы заметить какую-либо существенную разницу в производительности среди трех.

Перечисляемым#max_by, min_by , max и min было разрешено иметь необязательный аргумент начиная с Ruby версии 2.

Ответ №3:

Чтобы ускорить работу, я бы проверил минимальное значение при сопоставлении:

 hash = {"Hindi" => 60, "Dutch" => 93, "Greek" => 71}

hash.sort.map { |arr| arr[0] if arr[1] >= 60 }.compact

# or imo cleaner

hash.sort.select { |a| a[1] >= 60 }.map(amp;:first)