缩短长的 if else 语句

Ale*_*lex 1 ruby ruby-on-rails

我有一个很长的if else声明:

 rnd = rand(1..1000)
 if rnd >= 600
   0
 elsif rnd < 600 && rnd >= 350
   1
 elsif rnd < 350 && rnd >= 270
   2
 elsif rnd < 270 && rnd >= 200
   3
 elsif rnd < 200 && rnd >= 150
   4
 elsif rnd < 150 && rnd >= 100
   5
 elsif rnd < 100 && rnd >= 80
   6
 elsif rnd < 80 && rnd >= 50
   7
 elsif rnd < 50 && rnd >= 30
   8
 else
   9
 end
Run Code Online (Sandbox Code Playgroud)

我想缩短它。是否可以?我的 rubocop 对这个漫长的方法发誓。

spi*_*ann 7

我会从这样的事情开始:

RANGES = {
  (0...30) => 9,
  (30...50) => 8,
  (50...80) => 7,
  # ...
  (350...600) => 1,
  (600...1000) => 0
}

rnd = rand(1..1000)
RANGES.find { |k, _| k.cover?(rnd) }.last
Run Code Online (Sandbox Code Playgroud)


Mar*_* G. 5

已经很棒的答案了!只是插话,因为我怀疑 ruby​​ 可以通过case声明来处理这个问题,而且它似乎能够这样做:

rnd = rand(1..1000)

case rnd
when 600.. then 0
when 350...600 then 1
when 270...350 then 2
...
else 9
end
Run Code Online (Sandbox Code Playgroud)

无论采用何种方法,您都必须在某处指定范围,因此我认为在此处使用类似 case 语句的内容是合适的(抱歉!它不会将代码缩短多于几行)。使用散列也是一种很好的方法(并且可能允许您将散列移到其他地方),正如其他评论者已经表明的那样。

值得一提的是,与红宝石范围,..意味着该范围是包容性的,包括最后一个值(1..10包括10号),和...手段的范围是独占它不包括最后一个值。

最上面的情况600..是一个无限范围,这意味着它将匹配大于 600 的任何内容。(该功能是在 ruby​​ 2.6 中添加的)