检查范围集合中的整数

时间:2015-12-29 13:23:06

标签: ruby range

我试图找到确定给定整数在哪个范围内的最佳方法。 以此哈希为例:

score_levels = {
  1 => {'name' => 'Beginner', 'range' => 0..50}, 
  2 => {'name' => 'Intermediate', 'range' => 51..70},
  3 => {'name' => 'Pro', 'range' => 71..85},
  4 => {'name' => 'Expert', 'range' => 86..96},
  5 => {'name' => 'Master', 'range' => 97..100}
}

我想在得分时运行不同的逻辑,例如:

case score
when score_levels[1]['range']
  level_counters[1] += 1
when score_levels[2]['range']
  level_counters[2] += 1
when score_levels[3]['range']
  level_counters[3] += 1
end

有更通用的方法吗? 也许是这种精神的东西:

score_levels.each |key, val| {if val['range'].member?(score) then level_counters[key] += 1 }

谢谢!

3 个答案:

答案 0 :(得分:4)

由于范围不重叠并无缝覆盖0..100 - 您不需要显式范围,而是需要:

score_levels = [
  {id:1, name: 'Beginner', max_score:50},
  {id:2, name: 'Intermediate', max_score:70},
  {id:3, name: 'Pro', max_score:85},
  {id:4, name: 'Expert', max_score:96},
  {id:5, name:  'Master', max_score:100}
].sort_by{|v| v[:max_score]}

sort_by是可选的,但留在那里表示该数组应该排序

找到自己(假设分数不超过最大值并始终找到)

level_counters[ score_levels.find{|v| score <= v[:max_score]}[:id] ] += 1

答案 1 :(得分:3)

是的,有。

level_counters[score_levels.find{|_, h| h["range"].include?(score)}.first] += 1

答案 2 :(得分:0)

如果您要反复查找级别并需要高效地进行,请考虑构建一个单独的哈希:

score_to_level = score_levels.each_with_object({}) { |(k,v),h|
  v['range'].each { |v| h[v] = k} }
  #=> {0=>1, 1=>1, 2=>1, 3=>1, 4=>1, 5=>1, 6=>1, 7=>1, 8=>1, 9=>1,
  #    10=>1,..., 91=>4,
  #    92=>4, 93=>4, 94=>4, 95=>4, 96=>4, 97=>5, 98=>5, 99=>5, 100=>5} 

这当然假设每个范围包含有限数量的值(例如,不是(1.1..3.3))。