¿Determinar si una variable está dentro del rango?


134

Necesito escribir un bucle que haga algo como:

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

Pero hasta ahora hemos recorrido caminos equivocados en términos de sintaxis.

Respuestas:


306
si i.entre? (1, 10)
  hacer cosa 1 
elsif i.entre? (11,20)
  hacer cosa 2 
...

3
Esto también funciona para Datey DateTimeobjetos mientras ===que no.
Aditya

i.between?(1..10)no funcionará (si es así ..) supongo que debe haber una razón para ello
polaridad

¿Entre? necesitaría dos parámetros, no permitiría el rango.
Manish Nagdewani

55
¿Es inclusivo o exclusivo?
andrewcockerham

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

84

Use el ===operador (o su sinónimo include?)

if (1..10) === i

1
Tiene la ventaja de trabajar también con iser algo más que un número (como nil)
Christoffer Klang

44
No parecería una solución muy eficiente si el rango hubiera sido significativamente grande.
2013

66
Para el futuro lector, la forma alternativa if i === (1..10)no funcionará
Anwar

@rthbound, ¿por qué? (1..10000000000000000) No es una matriz. (1..10000000000000000) === 5000000000000000solo está haciendo una prueba "entre" bajo el capó
John La Rooy

1
@Anwar, ¿podrías explicar por qué no funciona a la inversa?
Govind Rai

70

Como dijo @Baldu, use el operador === o use case / when que internamente usa ===:

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

De todas las respuestas, este también es probablemente el más eficaz cuando tiene múltiples rangos.
xentek

40

si aún quisieras usar rangos ...

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

8

Por lo general, puede obtener un rendimiento mucho mejor con algo como:

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



1

Una respuesta más dinámica, que se puede construir en 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

Entonces, en este caso, los "rangos" realmente están cercados con nulos para capturar las condiciones de contorno.


-2

Para cuerdas:

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

# => verdadero

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.