Ruby 案例陈述:多个变量,每个变量具有多个可能性
起初我认为这种语法是有效的,但当只检查组的第一个值时,如果第一个值中的任何一个失败,它将返回locked。坏消息是Ruby 案例陈述:多个变量,每个变量具有多个可能性,ruby,Ruby,起初我认为这种语法是有效的,但当只检查组的第一个值时,如果第一个值中的任何一个失败,它将返回locked。坏消息是或操作数在此不起作用 def lock(a,b,c,d) case [a,b,c,d] when[(3||5||7), 2, (5||6), (8||9||0)] "unlocked" else "locked" end end lock(3, 2, 5, 8) lock(5, 2, 5, 0) lock(5, 2, 6, 8) lo
或
操作数在此不起作用
def lock(a,b,c,d)
case [a,b,c,d]
when[(3||5||7), 2, (5||6), (8||9||0)]
"unlocked"
else
"locked"
end
end
lock(3, 2, 5, 8)
lock(5, 2, 5, 0)
lock(5, 2, 6, 8)
lock(7, 2, 5, 8)
lock(7, 2, 6, 9)
我可以为每个变量执行if-else语句,但我希望有一种方法可以执行case语句,而不必执行多个when语句。我将选择循环数组,而不是使用
case
语句,如下所示:
def lock(a,b,c,d)
combination = [[3,5,7], [2], [5,6], [8,9,0]]
attempt = [a,b,c,d]
combination.each_with_index do |position, i|
return "locked" unless position.include?(attempt[i])
end
"unlocked"
end
产出:
lock(3, 2, 5, 8)
#=> "unlocked"
lock(5, 2, 5, 0)
#=> "unlocked"
lock(5, 2, 6, 8)
#=> "unlocked"
lock(7, 2, 5, 8)
#=> "unlocked"
lock(7, 2, 6, 9)
#=> "unlocked"
lock(1, 2, 3, 4)
#=> "locked"
为什么你的解决方案失败了 正如在他的著作中指出的那样,当与[(3 | 5 | 7),2,(5 | 6),(8 | 9 | 0)]结合时,
的计算结果是[3,2,5,8]
。这是因为括号中的每个表达式都是先求值的,因此,将其分解为:
(3 || 5 || 7)
#=> 3
2
#=> 2
(5 || 6)
#=> 5
(8 || 9 || 0)
#=> 8
这是因为|
正在计算值是否真实,即既不是nil
也不是false
。一旦表达式得到真实值,它将返回该值,不再进一步查看。因此,任何数字都将计算为truthy,因此,您将始终得到每个表达式的第一个数字
回到您的案例
语句,它与像这样编写它是完全一样的:
case [a,b,c,d]
when [3, 2, 5, 8]
"unlocked"
else
"locked"
end
现在请考虑< <代码>案例> /COD>语句将评估< <代码>案例> />代码中的对象是否与<<代码>中的< < /> >相同。因此,在中,您的案例将类似于:
[a,b,c,d] === [3, 2, 5, 8]
只有在您调用lock(3,2,5,8)
时,才会返回true
(和“unlocked”
)
也可以考虑在时使用多个值,使用<代码>,这样使用类似的东西将起作用:
case [a,b,c,d]
when [3, 2, 5, 8], [5, 2, 5, 0] then "unlocked"
else "locked"
end
其中when
相当于执行以下操作:
[a,b,c,d] === [3, 2, 5, 8] || [5, 2, 5, 0]
正如其他人所解释的,这个问题本身不适合使用案例陈述
因为变量看起来是数字,所以可以将它们转换为字符串并使用正则表达式
def lock(entry, valid)
r = /#{valid.map { |a| '['+a.join('|')+']' }.join }/
entry.join.match?(r) ? 'unlocked' : 'locked'
end
假设
valid = [[3, 5, 7], [2], [5, 6], [8, 9, 0]]
我们为valid
的值计算以下正则表达式:
r #=> /[3|5|7][2][5|6][8|9|0]/
试试看:
lock([3, 2, 5, 8], valid) #=> "unlocked"
lock([5, 2, 5, 0], valid) #=> "unlocked"
lock([5, 2, 6, 8], valid #=> "unlocked"
lock([7, 2, 5, 8], valid) #=> "unlocked"
lock([7, 2, 6, 9], valid) #=> "unlocked"
lock([5, 2, 4, 0], valid) #=> "locked"
我认为你误解了案例陈述的工作原理;它们使用相等运算符将case子句中的对象(在您的示例中,[a,b,c,d]
)与每个when子句中的对象进行比较。请注意,when子句中的对象只是一个数组,它将计算为[3,2,5,8]
,你的评论为我澄清了一切。当
的功能类似于if-else语句时,我认为是。所以你的意思是,当对象
时,它实际上只是在做case对象
==?如果是这样的话,|
不会抛出某种语法错误,这很有趣。我想这就是为什么我认为这是可能的。or运算符不会抛出语法错误,因为这是完全有效的语法3 | | 5
的计算结果仅为3
。真聪明!谢谢,我会考虑的。我只是想更多地理解case
语句,因为我从来没有使用过它们。我只是在写同样的语句,我认为这是最好的答案。@WolfgangTruong检查更新的答案,我希望它有助于更好地理解。