Déterminer si une variable est dans la plage?


134

J'ai besoin d'écrire une boucle qui fait quelque chose comme:

if i (1..10)
  do thing 1
elsif i (11..20)
  do thing 2
elsif i (21..30)
  do thing 3
etc...

Mais jusqu'à présent, ils ont emprunté les mauvais chemins en termes de syntaxe.

Réponses:


306
si i.entre? (1, 10)
  faire la chose 1 
elsif i.entre? (11,20)
  faire la chose 2 
...

3
Cela fonctionne également pour Dateet les DateTimeobjets, mais ===pas.
Aditya

i.between?(1..10)ne fonctionnera pas (si c'est le cas ..) Je suppose qu'il doit y avoir une raison à cela
nonopolarité

entre? aurait besoin de deux paramètres, il ne permettrait pas la plage.
Manish Nagdewani

5
est-ce inclusif ou exclusif?
andrewcockerham

1
@andrewcockerham inclus. 3.between?(1, 3) => true
Tyler James Young

84

Utilisez l' ===opérateur (ou son synonyme include?)

if (1..10) === i

1
A l'avantage de travailler avec iautre chose qu'un nombre (comme nil)
Christoffer Klang

4
Cela ne semblerait pas être une solution très efficace si la portée avait été considérablement large.
rthbound

6
Pour le futur lecteur, la méthode alternative if i === (1..10)ne fonctionnera pas
Anwar

@rthbound, pourquoi? (1..10000000000000000) n'est pas un tableau. (1..10000000000000000) === 5000000000000000fait juste un test "entre" sous le capot
John La Rooy

1
@Anwar pourriez-vous expliquer pourquoi cela ne fonctionne pas dans l'autre sens?
Govind Rai

70

Comme @Baldu l'a dit, utilisez l'opérateur === ou utilisez le cas / quand qui utilise en interne ===:

case i
when 1..10
  # do thing 1
when 11..20
  # do thing 2
when 21..30
  # do thing 3
etc...

de toutes les réponses, c'est probablement aussi la plus performante lorsque vous avez plusieurs plages.
xentek

40

si vous vouliez toujours utiliser des plages ...

def foo(x)
 if (1..10).include?(x)
   puts "1 to 10"
 elsif (11..20).include?(x)
   puts "11 to 20"
 end
end

8

Vous pouvez généralement obtenir de bien meilleures performances avec quelque chose comme:

if i >= 21
  # do thing 3
elsif i >= 11
  # do thing 2
elsif i >= 1
  # do thing 1



1

Une réponse plus dynamique, qui peut être intégrée dans Ruby:

def select_f_from(collection, point) 
  collection.each do |cutoff, f|
    if point <= cutoff
      return f
    end
  end
  return nil
end

def foo(x)
  collection = [ [ 0, nil ],
                 [ 10, lambda { puts "doing thing 1"} ],
                 [ 20, lambda { puts "doing thing 2"} ],
                 [ 30, lambda { puts "doing thing 3"} ],
                 [ 40, nil ] ]

  f = select_f_from(collection, x)
  f.call if f
end

Donc, dans ce cas, les «plages» sont en réalité simplement délimitées par des nils afin de capturer les conditions aux limites.


-2

Pour les cordes:

(["GRACE", "WEEKLY", "DAILY5"]).include?("GRACE")

# => vrai

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.