Использование bsearch
более производительно, чем find
, если вы можете гарантировать упорядоченный массив - O(log n)
против find
O(n)
- без каких-либо дополнительных затрат памяти (кроме кадров стека, хе-хе ). Кроме того, поскольку ваши диапазоны (предположительно) должны быть последовательными, без каких-либо пробелов между ними, вы можете просто указать пороговые значения.
Итак, если ваши индексы всегда равны "1..N", это работает:
def grade(points, scale)
scale.bsearch_index { |x| points < x }
end
scale = [0, 40, 50, 60, 70, 80, 101]
grade(39, scale)
# => 1
grade(40, scale)
# => 2
Если нет, то используйте это:
def grade(points, scale)
scale.to_a.bsearch { |upto, _| points < upto }.last
end
scale = {40 => 1, 50 => 2, 60 => 3, 70 => 4, 80 => 5, 101 => 6}
grade(39, scale)
# => 1
grade(40, scale)
# => 2