起初我认为这种语法有效,但似乎when
只会检查组的第一个值,如果任何第一个值失败,它将返回锁定状态。坏or
操作数在这里不起作用。
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语句。
答案 0 :(得分:2)
我会选择循环数组而不是使用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"
为什么你的解决方案失败了?
正如Hamms在comment中指出的那样,when
与[(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
这是因为||
正在评估值是否为 truthy ,即既不是nil
也不是false
。一旦表达式变为 truthy 值,它将返回该值并且不再查看。因此,任何数字都将评估为 truthy ,并且您将始终获得每个表达式的第一个数字。
回到你的case
声明,就像写它一样完全相同:
case [a,b,c,d]
when [3, 2, 5, 8]
"unlocked"
else
"locked"
end
现在考虑case
语句将评估case
中的对象是否与每个when
中的对象相等。所以,你的情况将是这样的:
[a,b,c,d] === [3, 2, 5, 8]
只有在您致电true
时才会返回"unlocked"
(和lock(3, 2, 5, 8)
)。
另外考虑一下你可以使用when
多个值,所以使用这样的东西会起作用:
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]
答案 1 :(得分: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"