2017-05-25 7 views
0

pig_latinメソッドを作成することが任されています。Rubyのメソッドでforループを実装する方法

Pig Latin is a made-up children's language that's intended to be confusing. It obeys a few simple rules (below) but when it's spoken quickly it's really difficult for non-children (and non-native speakers) to understand.

Rule 1: If a word begins with a vowel sound, add an "ay" sound to the end of the word.

Rule 2: If a word begins with a consonant sound, move it to the end of the word, and then add an "ay" sound to the end of the word.

(There are a few more rules for edge cases, and there are regional variants too, but that should be enough to understand the tests.)

私のすべてのテストでは、1つを保存して多くの単語を翻訳しています。

これは私のエラーです:

#translate 
    translates a word beginning with a vowel 
    translates a word beginning with a consonant 
    translates a word beginning with two consonants 
    translates two words 
    translates a word beginning with three consonants 
    counts 'sch' as a single phoneme 
    counts 'qu' as a single phoneme 
    counts 'qu' as a consonant even when it's preceded by a consonant 
    translates many words (FAILED - 1) 

Failures: 

    1) #translate translates many words 
    Failure/Error: expect(s).to eq("ethay ickquay ownbray oxfay") 

     expected: "ethay ickquay ownbray oxfay" 
      got: "ethay" 

     (compared using ==) 
    # ./spec/04_pig_latin_spec.rb:70:in `block (2 levels) in <top (required)>' 

Finished in 0.00236 seconds (files took 0.10848 seconds to load) 
9 examples, 1 failure 

Failed examples: 

rspec ./spec/04_pig_latin_spec.rb:68 # #translate translates many words 

そして、これが私の方法である:

def translate(str) 

    def add_ay(str) 
    return str + 'ay' 
    end 

    def word_begins_with_vowel(str) 
    if (!(str.match(' '))) && $vowels[str[0]] 
     return add_ay(str) 
    end  
    end 

    def begins_with_consonant(str) 
    if ((!$vowels[str[0]]) && (!$vowels[str[1]]) && (!$vowels[str[2]])) 
     first_three = str.split('').slice(0, 3).join(''); 
     str = str.slice(3, str.length - 1) 
     return str + first_three + 'ay' 
    end 
    if ((!$vowels[str[0]]) && (!$vowels[str[1]])) 
     first_two = str.split('').slice(0, 2).join(''); 
     str = str.slice(2, str.length - 1) 
     return str + first_two + 'ay' 
    end 
    if ((!$vowels[str[0]])) 
    first_char = str.split('').slice(0); 
    str = str.slice(1, str.length - 1) 
    return str + first_char +'ay' 
    end 
    end 

    def translates_two_words(str) 
    if (str.match(' ')) 
     str = str.split(' '); 
     first_char = str[1].split('').slice(0); 
     str[1] = str[1].slice!(1, str[1].length - 1); 

     return str[0] + 'ay' + ' ' + str[1] + first_char + 'ay' 
    end  
    end 

    def translates_many_words(str) 
     str = str.split(' '); 
     if str.length > 2 
     str.each do |item| 
      return begins_with_consonant(item) || word_begins_with_vowel(item) 
     end 
     end 
    end 

    $vowels = { 
    'a' => add_ay(str), 
    'e' => add_ay(str), 
    'i' => add_ay(str), 
    'o' => add_ay(str), 
    'y' => add_ay(str) 
    } 
    return translates_many_words(str) || word_begins_with_vowel(str) || begins_with_consonant(str) || translates_two_words(str) 
end 

私はこれが多くの単語の世話をするだろう理解します:

def translates_many_words(str) 
     str = str.split(' '); 
     if str.length > 2 
     str.each do |item| 
      return begins_with_consonant(item) || word_begins_with_vowel(item) 
     end 
     end 
    end 

が、そうではありません。 @theTinManが言うように

+0

'str.each ... return'ので、反復はあなたがやりたいことはありません、最初の反復の最初の値に戻ります。すべてのメソッドをラッピングメソッド内に埋め込むのは慣用的ではありません。最初の外観のために –

+0

、テストパスを作る - 'str.map {| item | starts_with_consonant(item)|| word_begins_with_vowel(item)} .join( '') ' –

+0

@AlexGolubenkoありがとう!状況に応じてソリューションを追加したり、何を意味するのかを表示してください。感謝します! –

答えて

2

return - 次の反復を辞退し、ちょうど最初の反復の最初の値を返す、私のコメントから、私が思うに、これは(あなたのコードの最小編集で)あなたのために働く必要があります:

def translates_many_words(str) 
    str = str.split(' '); 

    if str.length > 2 
    str.map do |item| 
     begins_with_consonant(item) || word_begins_with_vowel(item) 
    end.join(' ') 
    end 
end 

UPD さらに、私はあなたのコードをリファクタリングして、より読みやすくすることをお勧めします。 この方法の私の変異体である:

def translates_many_words(str) 
    str = str.split 

    # line under - is a shortcut from `return nil if str.size <= 2` 
    # `#size` is more relative to this context if you will count elements of array 
    return unless str.size > 2 

    # Now, when we excluded possibility of work with array that have less then 2 elements, 
    # we can continue with our iteration 
    str.map do |item| 
    begins_with_consonant(item) || word_begins_with_vowel(item) 
    end.join(' ') 
end 
+0

'; 'のUPDを確認することをお勧めします。行末には必要ないし、慣用句もありません。 'split( '')'はデフォルトの動作が空白で分割されるため、 'split'と書くことができます。 –

+0

@theTinManあなたの権利は、しかし、私が言っているように: "あなたのコードの最小編集で、UPDで、私のバリアントを見ることができます) –

+0

" UPD "または"更新 "または"編集 "あなたが元々それを含んでいたなら、どこに行ったかの情報。 SOはすべての質問と回答のリビジョン管理を維持しているので、何が変わったのか、いつ必要なのかを見ることができます。毎週通知と変更を行うよりも、明快さと可読性が重要です。 –

関連する問題