ruby 大写不适用于标题的第一个单词
ruby capitalize doesnt work for the first word of the title
下面的代码是除了'littleWords'和标题的第一个单词之外的所有单词都大写。 (即使属于littleWords,首字也要大写。)
def titleize (word)
littleWords = ["and", "the", "over", "or"]
words = Array.new
words = word.split(" ")
titleWords = Array.new
words.each {|word, index|
if index == 0
word = word.capitalize
else
unless littleWords.include?(word)
word = word.capitalize
end
end
titleWords << word
}
return titleWords.join(" ")
end
测试代码如下
it "does capitalize 'little words' at the start of a title" do
expect(titleize("the bridge over the river chao praya")).to eq("The Bridge over the River chao praya")
end
但它始终将第一个 'the' 大写为 'the' 而不是 'The'。我想知道我的代码的哪一部分是错误的。帮帮我...TT
您应该使用 each_with_index 而不是 each
来获得 index
正如您从 the documentation of Array#each
中看到的那样,它只产生一个块参数:
each { |item| block } → ary
# ↑↑↑↑↑↑
但是,您的块有两个参数:
words.each {|word, index|
# ↑↑↑↑↑↑↑↑↑↑↑↑↑
由于 each
只为块生成一个参数,第二个参数将始终是 nil
。 (除非元素恰好是 Array
,然后 word
将绑定到数组的第一个元素,而 index
将绑定到第二个元素。)并且由于 index
是总是 nil
,它永远不会等于 0
,因此永远不会进入条件的第一个分支。
但是,还有另一种迭代方法,它实际上为块生成两个参数,即元素及其索引,称为 Enumerable#each_with_index
:
words.each_with_index {|word, index|
# ↑↑↑↑↑↑↑↑↑↑↑
这就是使代码正常工作所需的全部更改。
这里,另一种不使用 each
或 each_with_index
的方式。
def titleize (word)
littleWords = ["and", "the", "over", "or"]
words = word.split(" ")
words[0].capitalize + " " + words[1..-1].map do |w|
littleWords.include?(w) ? w : w.capitalize
end.join(" ")
end
您可以将 String#gsub 与正则表达式和块一起使用。
def titlesize(str, little_words)
str.gsub(/[[:alpha:]]+/) { |w| little_words.include?(w) &
(Regexp.last_match.begin(0) > 0) ? w : w.capitalize }
end
当little_words
等于数组["and","the","over","of"],
titlesize "the days of wine and roses", little_words
#=> "The Days of Wine and Roses"
参见Regexp::last_match and MatchData#begin。 Regexp.last_match
可以用全局变量$~
代替。
下面的代码是除了'littleWords'和标题的第一个单词之外的所有单词都大写。 (即使属于littleWords,首字也要大写。)
def titleize (word)
littleWords = ["and", "the", "over", "or"]
words = Array.new
words = word.split(" ")
titleWords = Array.new
words.each {|word, index|
if index == 0
word = word.capitalize
else
unless littleWords.include?(word)
word = word.capitalize
end
end
titleWords << word
}
return titleWords.join(" ")
end
测试代码如下
it "does capitalize 'little words' at the start of a title" do
expect(titleize("the bridge over the river chao praya")).to eq("The Bridge over the River chao praya")
end
但它始终将第一个 'the' 大写为 'the' 而不是 'The'。我想知道我的代码的哪一部分是错误的。帮帮我...TT
您应该使用 each_with_index 而不是 each
来获得 index
正如您从 the documentation of Array#each
中看到的那样,它只产生一个块参数:
each { |item| block } → ary
# ↑↑↑↑↑↑
但是,您的块有两个参数:
words.each {|word, index|
# ↑↑↑↑↑↑↑↑↑↑↑↑↑
由于 each
只为块生成一个参数,第二个参数将始终是 nil
。 (除非元素恰好是 Array
,然后 word
将绑定到数组的第一个元素,而 index
将绑定到第二个元素。)并且由于 index
是总是 nil
,它永远不会等于 0
,因此永远不会进入条件的第一个分支。
但是,还有另一种迭代方法,它实际上为块生成两个参数,即元素及其索引,称为 Enumerable#each_with_index
:
words.each_with_index {|word, index|
# ↑↑↑↑↑↑↑↑↑↑↑
这就是使代码正常工作所需的全部更改。
这里,另一种不使用 each
或 each_with_index
的方式。
def titleize (word)
littleWords = ["and", "the", "over", "or"]
words = word.split(" ")
words[0].capitalize + " " + words[1..-1].map do |w|
littleWords.include?(w) ? w : w.capitalize
end.join(" ")
end
您可以将 String#gsub 与正则表达式和块一起使用。
def titlesize(str, little_words)
str.gsub(/[[:alpha:]]+/) { |w| little_words.include?(w) &
(Regexp.last_match.begin(0) > 0) ? w : w.capitalize }
end
当little_words
等于数组["and","the","over","of"],
titlesize "the days of wine and roses", little_words
#=> "The Days of Wine and Roses"
参见Regexp::last_match and MatchData#begin。 Regexp.last_match
可以用全局变量$~
代替。