Xác định nếu một biến nằm trong phạm vi?


134

Tôi cần phải viết một vòng lặp làm một cái gì đó như:

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

Nhưng cho đến nay đã đi sai đường dẫn về cú pháp.

Câu trả lời:


306
nếu tôi ở giữa? (1, 10)
  làm điều 1 
elsif i.b between? (11,20)
  làm điều 2 
...

3
Điều này cũng hoạt động cho DateDateTimecác đối tượng trong khi ===không.
Aditya

i.between?(1..10)sẽ không hoạt động (nếu có ..) Tôi cho rằng phải có một lý do cho nó
phân cực

giữa? sẽ cần hai tham số nó sẽ không cho phép phạm vi.
Manish Nagdewani

5
nó bao gồm hay độc quyền?
andrewcockerham

1
@andrewcockerham Bao gồm. 3.between?(1, 3) => true
Tyler James Young

84

Sử dụng ===toán tử (hoặc từ đồng nghĩa của nó include?)

if (1..10) === i

1
Có lợi ích tốt đẹp khi làm việc với imột cái gì đó khác hơn là một số (như nil)
Christoffer Klang

4
Sẽ không giống như một giải pháp rất hiệu quả nếu phạm vi đã lớn đáng kể.
rthbound

6
Đối với người đọc trong tương lai, cách khác if i === (1..10)sẽ không hiệu quả
Anwar

@rthbound, tại sao? (1..10000000000000000) không phải là một mảng. (1..10000000000000000) === 5000000000000000chỉ đang thực hiện bài kiểm tra "giữa" dưới mui xe
John La Rooy

1
@Anwar bạn có thể giải thích tại sao nó không hoạt động theo cách khác?
Govind Rai

70

Như @Baldu đã nói, hãy sử dụng toán tử === hoặc trường hợp sử dụng / khi sử dụng nội bộ ===:

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

trong tất cả các câu trả lời, đây cũng có thể là hiệu suất cao nhất khi bạn có nhiều phạm vi.
xentek

40

nếu bạn vẫn muốn sử dụng phạm vi ...

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

8

Bạn thường có thể có được hiệu suất tốt hơn rất nhiều với những thứ như:

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

8

Bạn đã có thể sử dụng
if (1..10).cover? i then thing_1 elsif (11..20).cover? i then thing_2

và theo tiêu chuẩn này trong Fast Ruby nhanh hơninclude?


Điều này thực sự nhanh hơn rất nhiều
Joe Half Face

5

Không phải là một câu trả lời trực tiếp cho câu hỏi, nhưng nếu bạn muốn ngược lại "bên trong":

(2..5).exclude?(7)

thật


Lưu ý rằng đó exclude?là một bổ sung Rails .
Jan Klimo

1

Một câu trả lời năng động hơn, có thể được xây dựng trong 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

Vì vậy, trong trường hợp này, "phạm vi" thực sự chỉ được rào lại bằng nils để bắt các điều kiện biên.


-2

Đối với Chuỗi:

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

# => đúng

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.