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

目標は、単語が母音で始まるかどうかを調べて、単語を「豚ラテン語」に翻訳する関数を実装することです。この場合、関数は単に「ay」を追加します。子音で始まる場合、最初の文字が最初の位置に母音になるまで、単語の最後に配置されます。

私が抱えている問題は、 while ループの開始時に保存した最初の文字を単語の最後の位置に割り当てるときに始まります。

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"

as("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)

上記の論理エラーにより、文字が でない場合は常に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

まだ 1 つの問題があります。母音を持たない単語はどうなりますか。ループは無限ループになります。修正する必要があります

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 に答える