无法保持在`include?`中找到的数组元素

我对Title类的要求如下。

  1. 采用像"the united states"这样的全小写字符串,并将每个单词的首字母大写( "The United States" )。
  2. 拿一个类似"ThE UnIted STatEs"的骆驼案例字符串"ThE UnIted STatEs""The United States"

以下代码满足它们:

 class Title attr_accessor :string def initialize(string) @string = string end def fix string2 = string.split(" ").map{ |string| string.capitalize }.join(" ") end end 

我添加了另一个条件:

  1. 如果字符串是"the""The""of""Of" ,则不会将其大写。

尝试使用如下map逻辑修改fix不起作用:

 class Title def fix string2 = string.split(" ").map{ |string| string.capitalize }.join(" ") string2.split(" ").map{ |string| (string.include?("of","Of","the","The") ? string.downcase : string.capitalize) }.join(" ") end end #=> Error: wrong number of arguments (2 for 1) 

有没有其他方法可以实现这个逻辑? 我不确定为什么这对我不起作用。 有人可以提供任何帮助/指导吗?

String #include只接受一个参数,这就是ArgumentError的来源。 相反,你可以这样做:

 [8] pry(main)> prepositions = ["of", "Of", "the", "The"] => ["of", "Of", "the", "The"] [9] pry(main)> string2.split(" ").map{ |string| prepositions.include?(string) ? string.downcase : string.capitalize }.join(" ") => "of Thy Self In the Capital" 

我更喜欢上述内容,它允许您轻松保留一个超出正常大小写方法的单词列表。 它易于阅读,易于添加等。也就是说,您可以使用不区分大小写的正则表达式匹配:

 string2.split(" ").map{ |string| string.match(/(the)|(of)/i) ? string.downcase : string.capitalize }.join(" ") 

使用gsub

您不需要将字符串转换为单词数组,映射单词,然后join 。 相反,只需使用带有块的String#gsubforms。

  小词 

你说你不想把某些词大写。 编辑经常将这些词称为“小词” 。 我们来定义一些:

  LITTLE_WORDS =%w {对于an或和} 
    #=> [“the”,“of”,“for”,“a”,“an”,“or”,“and”] 

  

我假设遇到的所有小词都是低级的,所有其他的词都要被低估和大写。 我们可以这样做:

 def fix(str) str.gsub(/\w+/) do |w| if LITTLE_WORDS.include?(w.downcase) w.downcase else w.capitalize end end end 

例子

我们来试试吧:

 fix("days of wine aNd roses") #=> "Days of Wine and Roses" fix("of mice and meN") #=> "of Mice and Men" 

嗯。 第二个例子有点问题。 据推测,我们应该把第一个词大写,不管它是否是一个小词。 有各种方法可以做到这一点。

#1修改所有单词后,将第一个单词大写

 def fix(str) str.gsub(/\w+/) do |w| if LITTLE_WORDS.include?(w.downcase) w.downcase else w.capitalize end end.sub(/^(\w+)/) { |s| s.capitalize } end fix("of mice and men") #=> "Of Mice and Men" 

请注意,我在正则表达式中引入了一个捕获组。 或者,您可以将倒数第二行更改为:

 end.sub(/^(\w+)/) { $1.capitalize } 

#2设置一个标志

 def fix(str) first_word = true str.gsub(/\w+/) do |w| if LITTLE_WORDS.include?(w.downcase) && !first_word w.downcase else first_word = false w.capitalize end end end fix("of mice and men") #=> "Of Mice and Men" 

#3使用索引

 def fix(str) str.gsub(/\w+/).with_index do |w,i| if LITTLE_WORDS.include?(w.downcase) && i > 0 w.downcase else w.capitalize end end end fix("of mice and men") #=> "Of Mice and Men" 

#4修改正则表达式

 def fix(str) str.gsub(/(^\w+)|\w+/) do |w| if $1.nil? && LITTLE_WORDS.include?(w.downcase) w.downcase else w.capitalize end end end fix("of mice and men") #=> "Of Mice and Men" 

更多问题

现在我们需要修复:

 fix("I bought an iPhone and a TV") #=> "I Bought an Iphone and a Tv"