Determinando se uma variável está dentro do intervalo?


134

Eu preciso escrever um loop que faz algo como:

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

Até agora, porém, seguimos os caminhos errados em termos de sintaxe.

Respostas:


306
se i.entre? (1, 10)
  fazer coisa 1 
(11,20)
  faça a coisa 2 
...

3
Isso também funciona para Datee DateTimeobjetos, enquanto ===não funciona.
— Aditya

i.between?(1..10)não vai funcionar (se for ..) Suponho que deve haver uma razão para isso
— nonopolarity

entre? precisaria de dois parâmetros que não permitiriam alcance.
— Manish Nagdewani

5
é inclusivo ou exclusivo?
— precisa saber é o seguinte

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

84

Use o ===operador (ou seu sinônimo include?)

if (1..10) === i

1
Tem a agradável vantagem de também trabalhar com isendo algo mais do que um número (como nil)
— Christoffer Klang

4
Não seria uma solução muito eficiente se o intervalo tivesse sido significativamente grande.
— Rthbound # 25/13

6
Para futuro leitor, a forma alternativa if i === (1..10)não funcionará
— Anwar

@rthbound, por quê? (1..10000000000000000) não é uma matriz. (1..10000000000000000) === 5000000000000000está apenas fazendo um "entre" teste sob o capô
— John La Rooy

1
@ Anwar, você poderia explicar por que não funciona da outra maneira?
— Govind Rai

70

Como o @Baldu disse, use o operador === ou caso de uso / quando o qual usar internamente ===:

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

de todas as respostas, esse também é provavelmente o melhor desempenho quando você tem vários intervalos.
— xentek

40

se você ainda queria usar intervalos ...

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

8

Geralmente, você pode obter um desempenho muito melhor com algo como:

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



1

Uma resposta mais dinâmica, que pode ser construída em 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

Portanto, neste caso, os "intervalos" são realmente limitados a zero para capturar as condições de contorno.


-2

Para cordas:

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

# => true

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.