การพิจารณาว่าตัวแปรอยู่ในช่วงหรือไม่?


136

ฉันต้องเขียนลูปที่ทำสิ่งที่ชอบ:

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

แต่จนถึงขณะนี้ได้ไปผิดเส้นทางในแง่ของไวยากรณ์

คำตอบ:


310
ถ้า i ระหว่าง? (1, 10)
  สิ่งที่ทำ 1 
เอลซิฟ i. ระหว่าง? (11,20)
  สิ่งที่ทำ 2 
...

3
นอกจากนี้ยังใช้ได้กับDateและDateTimeวัตถุในขณะที่===ไม่
Aditya

i.between?(1..10)จะไม่ทำงาน (ถ้าเป็น..) ฉันคิดว่าต้องมีเหตุผลสำหรับมัน
nonopolarity

ระหว่าง? จะต้องมีสองพารามิเตอร์ที่ไม่อนุญาตให้มีช่วง
Manish Nagdewani

6
มันรวมหรือพิเศษ?
andrewcockerham

2
@andrewcockerham รวม. 3.between?(1, 3) => true
Tyler James Young

86

ใช้ตัว===ดำเนินการ (หรือคำพ้องความหมายinclude?)

if (1..10) === i

1
มีประโยชน์ที่ดีในการทำงานกับiการเป็นอย่างอื่นที่ไม่ใช่ตัวเลข (ชอบnil)
Christoffer Klang

4
ดูเหมือนจะไม่ใช่โซลูชันที่มีประสิทธิภาพมากนักหากช่วงมีขนาดใหญ่มาก
rthbound

6
สำหรับผู้อ่านในอนาคตวิธีอื่นif i === (1..10)จะไม่ได้ผล
อันวาร์

@rthbound ทำไม? (1..10000000000000000) ไม่ใช่อาร์เรย์ (1..10000000000000000) === 5000000000000000กำลังทำการทดสอบ "ระหว่าง" ภายใต้ประทุน
John La Rooy

1
@Anwar คุณช่วยอธิบายได้ไหมว่าทำไมมันถึงใช้ไม่ได้?
Govind Rai

70

ตามที่ @Baldu กล่าวให้ใช้ตัวดำเนินการ === หรือกรณีการใช้งาน / เมื่อใช้ภายใน ===:

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

จากคำตอบทั้งหมดนี่อาจเป็นคำตอบที่มีประสิทธิภาพมากที่สุดเมื่อคุณมีหลายช่วง
xentek


8

โดยปกติคุณจะได้รับประสิทธิภาพที่ดีขึ้นมากด้วยสิ่งต่างๆเช่น:

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



1

คำตอบแบบไดนามิกมากขึ้นซึ่งสามารถสร้างได้ใน 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

ดังนั้นในกรณีนี้ "ช่วง" จึงเป็นเพียงการล้อมรั้วด้วย nils เพื่อที่จะจับเงื่อนไขขอบเขต


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.