如何在Ruby中的方法中实现for循环

时间:2017-05-25 21:08:44

标签: ruby

我的任务是创建pig_latin方法。

  

Pig Latin是一种化妆儿童的语言    混乱。它遵循一些简单的规则(下面),但是当它被说出来时    很快,非儿童(非本地人)非常困难    发言者)要明白。

     

规则1:如果单词以元音开头,请添加“ay”声音    这个词的结尾。

     

规则2:如果一个单词以辅音开头,请将其移至最后    单词,然后在单词的末尾添加“ay”声音。

     

(边缘案例还有一些规则,还有区域性规则   变体也是如此,但这应该足以理解测试。)

我所有的测试都是通过保存一,翻译很多单词。

这是我的错误:

#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

但事实并非如此。

1 个答案:

答案 0 :(得分:2)

正如@theTinMan所说,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