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.