2012-03-06 98 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