Почему в моем коде используются заглавные слова, если я не указал? - PullRequest
0 голосов
/ 09 марта 2020
class Book
    # write your code here
        attr_accessor :title

        def title= (title)

          @title = title.split()
          @title = @title.map {
              |x|
              index = @title.index(x)
               if x == 'and' or x == 'in' or x == 'of' or x == 'the' or x == 'a' or x == 'an' and index != 0

                x = x       
              else
                x.capitalize
              end
          }
          @title = @title.join(" ")
          return @title
        end              
    end

Это упражнение из Проекта Ruby по Проекту Один. Речь идет о том, чтобы заглавные буквы книги были привязаны к определенным условиям жизни, если слово является предлогом, статьей или соединением, тогда не пишите его заглавными буквами, если оно не встречается в начале названия, а затем пишите заглавными буквами. Я написал код для него, но он не работает, как вы можете видеть:

index = @title.index(x)
if x == 'and' or x == 'in' or x == 'of' or x == 'the' or x == 'a' or x == 'an' and index != 0
  x = x
else 
  x.capitalize
end

Но опять-таки он не работает

expected: "The Man in the Iron Mask"
got: "The Man in The Iron Mask"

Второй The становится заглавным также, когда я сказал в утверждении if, что если оно не равно первому слову, не пишите его с заглавной буквы, но оно по-прежнему пишется с заглавной буквы.

Ответы [ 2 ]

4 голосов
/ 09 марта 2020

Поскольку index(x) всегда возвращает первое совпадение.

Я бы переписал его так:

class Book    
  attr_accessor :title

  DO_NOT_CAPITALIZE = %w[and in of the a an]

  def title=(title)
    words = title.split.map do |word|
      # capitalize all word that are not excluded
      DO_NOT_CAPITALIZE.include?(word) ? word : word.capitalize
    end

    # always capitalize the first word
    @title = words.join(' ').capitalize
  end              
end
0 голосов
/ 10 марта 2020

Проблема с вашим кодом была идентифицирована. Один из способов получить желаемый результат - использовать String # gsub с простым регулярным выражением.

LITTLE_WORDS = %w| a an and in of the |
  #=> ["a", "an", "and", "in", "of", "the"] 
LWR = /\b#{LITTLE_WORDS.join('|')}\b/i
  #=> /\ba|an|and|in|of|the\b/i

def normalize(str)
  str.gsub(/\S+/) do |word|
    if Regexp.last_match.begin(0).zero?
      word.capitalize
    else
      word.match?(LWR) ? word.downcase : word.capitalize
    end
  end
end

normalize("tHe cat and    A hAt")
  #=> "The Cat and    a Hat"

См. Regexp :: last_match (аналогично значению глобальной переменной $~) и MatchData # begin . Обратите внимание, что это сохраняет интервал в строке.

В издательской индустрии такие статьи, предлоги и союзы часто называют «маленькими словами» и пишут " "," an "," и "," in "," of "," the ".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...