2017-06-05 32 views
0

起初我以为这句法工作,但它似乎when将仅检查组的第一个值,如果有第一个值的失败,它将返回锁定。坏or操作数在这里不起作用。Case语句:有多种可能性多个变量对每个变量

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) 

我可以为每个变量做一个,如果else语句,但我希望有办法做一个case语句,而无需进行多次的时候语句。

+1

我想你误会如何案例陈述的工作;他们将case子句中的对象(在你的情况下,'[a,b,c,d]')与使用相等运算符的每个when子句中的对象进行比较。 – Hamms

+1

请注意,when子句中的东西只是一个将评估为“[3,2,5,8]”的数组,而不是奇迹般地会与各种数组相匹配的数组 – Hamms

+0

您的评论清除了我。我认为“when”功能就像if语句一样。那么,你说的是,当对象是''case''''时' 如果是这样,'||'不会引发某种语法错误。我想这就是为什么我认为这是可能的。 –

回答

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对象是与一个在每个when等于case声明将评估。所以,你的情况会是这样的:

[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] 
+0

这很聪明!谢谢我会考虑它。这只是我试图获得更多的理解'case'语句,因为我从来没有使用它们。 –

+0

我只是写同样的,我认为这是最好的答案。 –

+1

@WolfgangTruong检查更新的答案,我希望它有助于获得更好的理解。 – Gerry

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"