无法保持在`include?`中找到的数组元素
我对Title
类的要求如下。
- 采用像
"the united states"
这样的全小写字符串,并将每个单词的首字母大写("The United States"
)。 - 拿一个类似
"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
我添加了另一个条件:
- 如果字符串是
"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"