2017-06-05 81 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"