确定变量是否在范围内?


134

我需要编写一个类似以下内容的循环:

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

但是到目前为止,在语法方面走了错误的道路。

Answers:


306
如果i.between(1,10)
  做事情1 
elsif i.between(11,20)
  做事情2 
...

3
这也适用于DateDateTime对象,===而不适用于。
Aditya

i.between?(1..10)将无法正常工作(如果是..)我想一定有它的一个原因
nonopolarity

之间?将需要两个参数,不允许范围。
Manish Nagdewani

5
是包容性还是排他性?
andrewcockerham

1
@andrewcockerham包含所有内容。3.between?(1, 3) => true
泰勒·詹姆斯·杨

84

使用===运算符(或其同义词include?

if (1..10) === i

1
具有与i数字以外的其他事物一起工作的好处(例如nil
Christoffer Klang

4
如果范围很大,这似乎不是一个非常有效的解决方案。
rthbound

6
对于未来的读者来说,这种替代方法if i === (1..10)将行不通
Anwar

@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

因此,在这种情况下,“范围”实际上只是用nil围起来,以捕捉边界条件。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.