¿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.