我正在尝试构建一种方法,你可以取出每个单词的第一个字母并将其大写。我把它写成
def titleize(name)
name.scan(/\w+/) { |x| x.capitalize! }
end
它只是无法正常工作。它不会大写和写信。我做了一些搜索,最终找到答案Capitalizing titles。它写成
def titleize(name)
name.split(" ").each { |x| x.capitalize! }.join(" ")
end
为什么我的代码根本没有大写呢?如果我添加了一个put语句并将其写为
def titleize(name)
name.scan(/\w+/) { |x| puts x.capitalize! }
end
它会用大写字母输出“hi there”但是=>仍然只是“喜欢那里”我错过了什么?
答案 0 :(得分:2)
更正后的代码:
def titleize(name)
name.scan(/\w+/).each { |x| x.capitalize! }.join(' ')
end
p titleize("ayan roy") #=>"Ayan Roy"
让我们看看为什么你的工作不起作用:
def titleize(name)
name.scan(/\w+/)
end
p titleize("ayan roy") #=>["ayan", "roy"]
现在,您的行name.scan(/\w+/) { |x| x.capitalize! }
,x
将作为"ayan", "roy"
传递。现在看下面的内容:
def titleize(name)
name.scan(/\w+/) { |x| p x.capitalize! }
end
p titleize("ayan roy")
输出:
"Ayan"
"Roy"
"ayan roy"
正如String#scan
所说:
扫描(模式){|匹配,... | block}→str - 如果给出了块,则scan将返回调用它的
receiver
。两种形式都通过str迭代,匹配模式(可能是Regexp或String)。对于每个匹配,生成结果并将其添加到结果数组或传递给块。
答案 1 :(得分:2)
scan
返回/产生新字符串,永远不会修改源字符串。也许你想要gsub
。
def titleize(name)
name.gsub(/\w+/) {|x| x.capitalize }
end
或者更好地使用titleize gem中可能更正确的实现。
答案 2 :(得分:1)
您的代码不起作用,因为#scan
返回新的String
对象,这些对象是Regexp的结果并将它们传递给块。所以在你的方法中你基本上接受了这些新对象,通过调用#capitalize!
来改变它们,但之后从未在任何地方使用它们。
你应该这样做:
def titleize(name)
name.scan(/\w+/).each { |x| x.capitalize! }.join(' ')
end
但这对我来说似乎更具可读性:
def titleize2(name)
name.split(' ').each { |w| w.capitalize! }.join(' ')
end
但请注意,这些方法不会改变传递的原始参数。
答案 3 :(得分:0)
scan
的块形式返回原始字符串,无论您在块中执行什么操作。 (我想你可以通过直接引用它来改变块中的原始字符串,但不建议改变你正在迭代的东西。)而是做你的split
变体,而不是each
,collect
后跟join
:
name.split(" ").collect { |x| x.capitalize }.join(" ")
这适用于包含数字和标点符号的标题。