Ruby - 如何缩短我的方法

时间:2016-09-13 00:51:23

标签: ruby

我在这里有一个哈希:

VALID_CHOICES = {
  'r' => 'rock',
  'p' => 'paper',
  'sc' => 'scissors',
  'l' => 'lizard',
  'sp' => 'spock'
}

这里基本比较一种方法:

def win?(first, second)
  (first == 'sc' && second == 'p') ||
    (first == 'p' && second == 'r') ||
    (first == 'r' && second == 'l') ||
    (first == 'l' && second == 'sp') ||
    (first == 'sp' && second == 'sc') ||
    (first == 'sc' && second == 'l') ||
    (first == 'l' && second == 'p') ||
    (first == 'p' && second == 'sp') ||
    (first == 'sp' && second == 'r') ||
    (first == 'r' && second == 'sc')
end

如何在非常简洁的代码中重写我的方法,这意味着完全相同的事情?任何的想法?是否可以使用哈希来做到这一点?

2 个答案:

答案 0 :(得分:7)

您应该为每个令牌赢得的内容定义明确的规则:

WINS = {
  'r' => %w{l sc},
  'p' => %w{r sp},  
  'sc' => %w{p l},
  'l' => %w{p sp},
  'sp' => %w{r sc}
}

现在您可以使用简单的查找来确定胜利:

def win?(first, second)
  WINS[first].include?(second)
end

虽然可能有几种“聪明”的方法可以避免像WINS这样的显式结构,但显式规则更容易理解 - 因此更易于维护。代码中的简洁性被认为是一个积极的属性,它提高了代码的可读性。导致代码难以理解的极端的简洁性是要努力争取的东西。

答案 1 :(得分:1)

除了user2864740's commentCary Swoveland's explanation之外,您还可以使用哈希将“获胜对”映射到各自的动词:

WINS = {
  %w[scissors paper]    => 'cuts',
  %w[paper    rock]     => 'covers',
  %w[rock     lizard]   => 'crushes',
  %w[lizard   spock]    => 'poisons',
  %w[spock    scissors] => 'smashes',
  %w[scissors lizard]   => 'decapitates',
  %w[lizard   paper]    => 'eats',
  %w[paper    spock]    => 'disproves',
  %w[spock    rock]     => 'vaporizes',
  %w[rock     scissors] => 'crushes'
}

如果键的第一项胜过第二项,则返回相应的动词:

WINS[['paper', 'rock']] #=> "covers"

nil如果不是:

WINS[['rock', 'paper']] #=> nil

在你的方法中:

def win?(first, second)
  WINS.has_key?([first, second])
end

或检查双方:

if WINS.has_key?([first, second])
  # first wins
elsif WINS.has_key?([second, first])
  # second wins
else
  # tie
end

或者更详细:

def result(first, second)
  if verb = WINS[[first, second]]
    "first wins: #{first} #{verb} #{second}" 
  elsif verb = WINS[[second, first]]
    "second wins: #{second} #{verb} #{first}" 
  else
    "tie"
  end
end

result('rock', 'scissors')
#=> "first wins: rock crushes scissors"

result('spock', 'lizard')
#=> "second wins: lizard poisons spock"

result('paper', 'paper')
#=> "tie"

当然,您也可以使用缩写(scprlsp)代替整个单词。