0

我正在尝试使用 Test-First 材料来学习 Ruby,但我被困在了这一点上。这是我的代码:

def translate(word)
  word=word.split("")
  while (!vowel(word[0])) do 
    first_letter=word[0]
    word.each_index do |i|
        word[i]=word[i+1]
    end
    word[word.length-1]=first_letter
  end

  return word.join + "ay"
end

def vowel(letter)
  if letter == ("a" || "e" || "i" || "o" || "u")
    return true
  end
end

目标是通过查看单词是否以元音开头来实现将单词翻译为“pig latin”的函数。如果是这种情况,该函数只是附加“ay”。如果它以辅音开头,它将第一个字母放在单词的末尾,直到第一个位置有一个元音。

将我在 while 循环开始时保存的第一个字母分配给 word 的最后一个位置时,我遇到的问题是

word[word.length-1]=first_letter

这会导致程序无限循环。

测试基于字符串“banana”,处理后应为“ananabay”。在这种情况下,first_letter 包含“b”。所以我测试了为单词的最后一个位置分配不同的字母,除了“b”之外的所有东西都很好。我没有得到的是,while 块不取决于最后一个字母,而是取决于单词的第一个字母,它仍然会导致一个无限循环,将“b”分配给 word[word.length-1]。

我会非常感谢一些见解。

4

1 回答 1

2

注意

letter == ("a" || "e" || "i" || "o" || "u")

相当于

letter == "a"

将评估为("a" || "e" || "i" || "o" || "u")恰好"a"在这种情况下的第一个真实值。

你需要的是

(letter == "a") || (letter == "e") || (letter == "i") || (letter == "o") || (letter == "u")

也可以写成:

["a","e","i","o","u"].include?(letter)

或者

%w(a e i o u).include?(letter)

或者

"aeiou".chars.include?(letter)

由于上述逻辑错误,只要 letter is not ,该vowel方法就会返回,如果有一个单词不包含 vowel ,则循环永远不会终止。因此,需要将其更正为如下所示。此外,当我们这样做时,让我们添加到方法名称以指示它将返回一个布尔值。nil"a"awhile?

def vowel?(letter)
  "aeiou".chars.include?(letter)
end

将字符串的第一个字符移动到字符串的末尾也可以通过使用如下代码来简化:

word = word[1..-1].concat(word[0])

让我们将这个逻辑提取到一个新方法中:

def rotate(word)
    word[1..-1].concat(word[0])
end

您还可以while通过切换到until表达式来简化循环。

word = rotate(word) until vowel?(word.chars.first)

因此,您的translate方法可以简化为如下所示:

def translate(word)
  word = rotate(word) until vowel?(word.chars.first)
  word.concat("ay")
end

还有一个问题,没有元音的单词会发生什么情况,循环将是无限循环。我们需要修理它

def translate(word)
  if word.chars.any? { |i| vowel?(i) }  
    word = rotate(word) until vowel?(word.chars.first)
  end
  word.concat("ay")
end

完整代码:

def translate(word)
  if word.chars.any? { |i| vowel?(i) }  
    word = rotate(word) until vowel?(word.chars.first)
  end
  word.concat("ay")
end

def rotate(word)
    word[1..-1].concat(word[0])
end

def vowel?(letter)
  "aeiou".chars.include?(letter)
end


p translate("banana")
#=> "ananabay"

p ["pig", "banana", "trash", "happy", "duck", "glove"].map(&method(:translate))
#=> ["igpay", "ananabay", "ashtray", "appyhay", "uckday", "oveglay"]
于 2016-01-26T11:24:36.850 回答