我想检查输入是否是四个数字1,2,3,4中的一个。如果不是,则应该有错误消息。我从这开始
n = gets.chomp.to_i
if n != 1 && n != 2 && n != 3 && n != 4
puts 'invalid input'
end
在其他语言中也会发生很多这种情况。如何缩短上述条件n != 1 && n != 2 && n != 3 && n != 4
?
答案 0 :(得分:8)
我会使用可能Range#cover?
的faster than include?
:
number = gets.chomp.to_i
puts('invalid input') unless (1..4).cover?(number)
答案 1 :(得分:5)
最快的检查:
if n < 1 || n > 4
答案 2 :(得分:3)
嗯,有case
声明:
case num
when 1,2,3,4
puts "it's ok"
else
puts "it's not ok"
end
例如:
[0, 1, 4, 5].each do |num|
case num
when 1,2,3,4
puts "#{num} is ok"
else
puts "#{num} is not ok"
end
end
# >> 0 is not ok
# >> 1 is ok
# >> 4 is ok
# >> 5 is not ok
或者有点DRYer:
[0, 1, 4, 5].each do |num|
puts case num
when 1,2,3,4
"#{num} is ok"
else
"#{num} is not ok"
end
end
# >> 0 is not ok
# >> 1 is ok
# >> 4 is ok
# >> 5 is not ok
而且,由于when
允许范围,因此您可以使用when 1 .. 4
。
虽然我很欣赏基准测试结果显示使用case
的速度最快,但没有任何意义,因为Casper应该是这样的。这是我发现的:
require 'fruity'
n = 1
compare do
casper1 { n < 1 || n > 4 }
casper2 { n >= 1 && n <= 4 }
casper3 { 1 <= n && n <= 4 }
sagarpandya82 {n.between?(1,4)}
spickerman {(1..4).cover?(n)}
reitermarkus {[1, 2, 3, 4].include?(n)}
ttm {case n;when 1,2,3,4;true;else;false;end}
end
# >> Running each test 262144 times. Test will take about 11 seconds.
# >> casper2 is similar to casper3
# >> casper3 is faster than ttm by 2x ± 1.0
# >> ttm is faster than casper1 by 2x ± 1.0 (results differ: true vs false)
# >> casper1 is faster than sagarpandya82 by 3x ± 1.0 (results differ: false vs true)
# >> sagarpandya82 is similar to spickerman
# >> spickerman is faster than reitermarkus by 2x ± 0.1
在多次运行时,casper2
和casper3
将以最快和最快的速度交替,然后在case
中使用ttm
。
随着更多值的添加,结果会发生变化。特别是,我认为include
和when 1,2,3,4
测试会受到严重影响。
只是为了表明没有必要折叠空间,或者换句话说,空白没有区别:
require 'fruity'
n = 1
compare do
ttm1 {case n;when 1,2,3,4;true;else;false;end}
ttm2 {case n; when 1,2,3,4; true; else; false; end}
ttm3 {
case n
when 1,2,3,4
true
else
false
end
}
end
# >> Running each test 131072 times. Test will take about 2 seconds.
# >> ttm1 is similar to ttm3
# >> ttm3 is similar to ttm2
有了Fruity,当你看到这些“类似于”的结果时,它们往往会按顺序交替,因为速度的差异通常是系统在测试过程中摆动的结果。
最后,将when 1,2,3,4
与when 1..4
进行比较:
require 'fruity'
n = 1
compare do
ttm1 {
case n
when 1,2,3,4
true
else
false
end
}
ttm2 {
case n
when 1..4
true
else
false
end
}
end
# >> Running each test 131072 times. Test will take about 2 seconds.
# >> ttm1 is faster than ttm2 by 8x ± 10.0
答案 3 :(得分:2)
我会使用Range
和unless
- 语句而不是if
:
unless (1..4).include?(n)
puts 'invalid input'
end
答案 4 :(得分:2)
如果你的范围是关节,你可以使用
n.between?(1,4)
我对最快的解决方案感到好奇,令我惊讶的是case
解决方案,无论是在范围内外的n
,还是在Windows 7下至少在MRI 1.9.3上。只有坑,它也是最长的解决方案..
Benchmark.bm do |x|
x.report {r.times {n < 1 || n > 4}}
x.report {r.times {n.between?(1,4)}}
x.report {r.times {(1..4).cover?(n)}}
x.report {r.times {[1, 2, 3, 4].include?(n)}}
x.report {r.times {case n;when 1,2,3,4;true;else;false;end}}
end
给出
user system total real
0.093000 0.000000 0.093000 ( 0.093600)
0.141000 0.000000 0.141000 ( 0.140400)
0.140000 0.000000 0.140000 ( 0.140400)
0.265000 0.000000 0.265000 ( 0.265200)
0.063000 0.000000 0.063000 ( 0.062400)
答案 5 :(得分:1)
您可以在数组中定义包含元素,并使用n
检查include?
是否为[1, 2, 3, 4].include?(n)
:
{{1}}
答案 6 :(得分:0)
其他帖子中的答案会在文字中回答您的问题,但以下是我在标题中对您的问题的回答:
编写此条件的更短方法n!= 1 || n!= 2 || n!= 3 ||在Ruby中n!= 4 n!= 1 || n!= 2 || n!= 3 ||在Ruby中n!= 4
表达式:true
总是等同于此。如果你想把它放在一个条件下,概念上最简单的就是不要使用任何条件。没有条件,只需在这种条件下写下你想做的事情。