2012-03-06 100 views
1

讓我先說這個,說我是Ruby的新手。Ruby和if語句

我試圖做這樣的事情:

raise NoSuchStrategyError unless ((player1[1].downcase && player2[1].downcase) == ("p" || "r" || "s")) 

然而,由於預期它不工作。它只承認第一個參數是否是「p」。如果它是「r」或「s」,它會拋出錯誤。我不得不寫出來的很長的路要走這樣,它的工作:

raise NoSuchStrategyError unless player1[1].downcase == "p" or player1[1].downcase == "s" or player1[1].downcase == "r" 
raise NoSuchStrategyError unless player2[1].downcase == "p" or player2[1].downcase == "s" or player2[1].downcase == "r" 

是否有更好的方法來做到這一點速記?

+0

在Python中,如果在['a','b','c']'中做了'if foo'。我很想知道Ruby是否也可以做到這一點。 – Blender 2012-03-06 07:22:07

+0

@Blender事實上,只有通過['Enumerable#include?'](http://ruby-doc.org/core-1.9.3/Enumerable.html#method-i-include-3F): '['a','b','c']。include? foo'。 (儘管嚴格地說['Array'覆蓋'include?'](http://ruby-doc.org/core-1.9.3/Array.html#method-i-include-3F)。) – 2012-03-06 07:37:25

+0

我意識到我是有點晚了,但我認爲我不能跟着我的其他責任跟上全班的速度。我試圖通過它,因爲我得到時間 – Calihan 2012-03-06 07:44:48

回答

2

這是因爲||返回到它的第一個參數是truthy 。在這種情況下,由於"p"是truthy,因此("p" || "r" || "s")總是返回"p"。認識到這一點,你的第一個語句可以等價地改寫爲:

raise NoSuchStrategyError unless ((player1[1].downcase && player2[1].downcase) == "p" 

由於攪拌機暗示在他對Python的評論,你可以這樣做:

raise NoSuchStrategyError unless ['p', 'r', 'y'].include?(player1[1].downcase) && ['p', 'r', 'y'].include?(player2[1].downcase) 

或更簡潔:

raise NoSuchStrategyError unless [player1[1].downcase, player2[1].downcase].all? { |c| %w[p r s].include? c } 

此外,在Ruby中使用and & or時要小心,它們不同於&& & ||。你可以(也應該)read more about the difference

1

你可以把它簡化這樣的:

raise NoSuchStrategyError unless (%w(a b c).include?(player1[1].downcase) && %w(a b c).include?(player2[1].downcase)) 

編輯

一個更簡單的解決方案:

raise NoSuchStrategyError if ("pry"[player1[1].downcase] || "pry"[player2[1].downcase]) 
+0

我認爲儘管'pry「[player1 [1] .downcase]'很簡短,但是使用'pry''代替一組單個元素會丟失一些正在做什麼的意圖字符。 – 2012-03-06 19:25:57

1

在你的方法('p' || 'r' || 's')總是返回「P」,因爲在Ruby中,除了nilfalse一切true包括0。因此,除了「P」,你的方法失敗。


嘗試使用Array#include?方法。

plays = ['p', 'r', 's'] 

raise NoSuchStrategyError unless (plays.include?(player1[1].downcase) && 
            plays.include?(player2[1].downcase) 
           ) 
2

你可能只是做:

"pry".include?(player1[1].downcase) 

與您的代碼真正的問題是你如何構建它。當你發現自己宣稱像PLAYER1和player2變量,然後寫一堆重複的代碼用這些變量工作,其通常是你需要聲明一個「玩家」類線索:

class Player 

    def initialize(name) 
    @name = name 
    @strategy = "goofy" 
    end 

    def valid_strategy? 
    return "pry".include?(@strategy) 
    end 

end 

然後你行看起來像這樣:

raise NoSuchStrategyError unless @player.valid_strategy? 
+1

甚至更​​短,''撬'[player1 [1] .downcase]' – pduersteler 2012-03-06 08:37:57