Bir değişkenin aralık dahilinde olup olmadığını belirleme?


134

Gibi bir şey yapan bir döngü yazmak gerekir:

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

Ancak şu ana kadar sözdizimi açısından yanlış yollar izledi.

Yanıtlar:


306
i. arasında mı? (1, 10)
  bir şey yap 1 
elsif i. arasında? (11,20)
  bir şey yap 2 
...

3
Bu aynı zamanda çalışır Dateve çalışmazken DateTimenesneler ===.
— Aditya

i.between?(1..10)işe yaramazsa (varsa ..) bunun bir nedeni olmalı
— nonopolarity

arasında? aralığa izin vermeyen iki parametreye ihtiyaç duyar.
— Manish Nagdewani

5
kapsayıcı mı yoksa özel mi?
— andrewcockerham

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

84

Kullanın ===operatörü (veya eşanlamlı include?)

if (1..10) === i

1
Bir inumaradan başka bir şey olmakla da çalışmanın iyi bir yararı var (örneğin nil)
— Christoffer Klang

4
Aralık önemli ölçüde geniş olsaydı çok verimli bir çözüm gibi görünmüyordu.
— rthbound

6
Gelecekteki okuyucu için alternatif yol if i === (1..10)işe yaramaz
— Anwar

@rthbound, neden? (1..10000000000000000) bir dizi değil. (1..10000000000000000) === 5000000000000000sadece kaputun altında bir "arasında" testi yapıyor
— John La Rooy

1
@Anwar neden başka şekilde çalışmadığını açıklayabilir misiniz?
— Govind Rai

70

@Baldu'nun dediği gibi, === operatörünü kullanın veya dahili olarak === kullanan case / kullanın:

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

tüm cevaplar arasında, bu muhtemelen birden fazla aralığınız olduğunda en yüksek performanstır.
— xentek

40

hala aralık kullanmak istiyorsanız ...

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

8

Genellikle aşağıdaki gibi bir şeyle çok daha iyi performans elde edebilirsiniz:

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



1

Ruby'de oluşturulabilecek daha dinamik bir cevap:

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

Yani, bu durumda, "aralıklar" sınır koşullarını yakalamak için gerçekten sadece nils ile çevrelenmiştir.


-2

Dizeler için:

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

# => True

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.