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.