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.