Determinare se una variabile rientra nell'intervallo?


134

Ho bisogno di scrivere un ciclo che faccia qualcosa del tipo:

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

Ma finora hanno seguito strade sbagliate in termini di sintassi.

Risposte:


306
se i. tra? (1, 10)
  fai cosa 1 
elsif i.b Between? (11,20)
  fai cosa 2 
...

3
Questo funziona anche per Datee DateTimeoggetti mentre ===non lo fa.
Aditya,

i.between?(1..10)non funzionerà (se lo è ..) suppongo ci debba essere una ragione per questo
polarità

fra? avrebbe bisogno di due parametri non consentirebbe l'intervallo.
Manish Nagdewani,

5
è inclusivo o esclusivo?
Andrewcockerham,

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

84

Usa l' ===operatore (o il suo sinonimo include?)

if (1..10) === i

1
Ha il bello vantaggio di lavorare anche con l' iessere qualcos'altro che un numero (come nil)
Christoffer Klang

4
Non sembrerebbe una soluzione molto efficiente se la gamma fosse stata significativamente ampia.
rthbound il

6
Per il futuro lettore, il modo alternativo if i === (1..10)non funzionerà
Anwar,

@rthbound, perché? (1..10000000000000000) non è un array. (1..10000000000000000) === 5000000000000000sta solo facendo un test "tra" sotto il cofano
John La Rooy,

1
@Anwar potresti spiegarmi perché non funziona diversamente?
Govind Rai,

70

Come ha detto @Baldu, utilizzare l'operatore === o il caso d'uso / quando che utilizza internamente ===:

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

di tutte le risposte, questo è probabilmente anche il più performante quando hai più intervalli.
xentek,

40

se volevi ancora usare gli intervalli ...

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

8

Di solito puoi ottenere prestazioni molto migliori con qualcosa del tipo:

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



1

Una risposta più dinamica, che può essere costruita in 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

Quindi, in questo caso, gli "intervalli" sono in realtà recintati con zero per catturare le condizioni al contorno.


-2

Per archi:

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

# => True

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.