J'essaie de trouver le meilleur moyen de déterminer dans quelle plage se trouve un entier donné. Prenez ce hachage par exemple:

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}
}

Je voudrais exécuter une logique différente en fonction d'un score, quelque chose comme:

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

Y a-t-il une manière plus générique de le faire? Peut-être quelque chose dans cet esprit:

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

Merci!

3
Tzvika Mordoch 29 déc. 2015 à 16:23

3 réponses

Meilleure réponse

Oui il y a.

level_counters[score_levels.find{|_, h| h["range"].include?(score)}.first] += 1
3
sawa 29 déc. 2015 à 14:13

Si vous recherchez des niveaux à plusieurs reprises et que vous devez le faire efficacement, envisagez de créer un hachage séparé:

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} 

Ceci suppose bien sûr que chaque plage contient un nombre fini de valeurs (pas (1.1..3.3), par exemple).

0
Cary Swoveland 29 déc. 2015 à 20:14

Étant donné que les plages ne se chevauchent pas et couvrent de manière transparente 0..100, vous n'avez pas besoin de plages explicites, mais plutôt de quelque chose comme:

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 est facultatif, mais laissé là pour indiquer que le tableau doit être trié

Et se trouver (suppose que le score ne dépasse pas le maximum et est toujours trouvé)

level_counters[ score_levels.find{|v| score <= v[:max_score]}[:id] ] += 1
4
Vasfed 29 déc. 2015 à 23:03