I've been given a string. First, I transform it into a array and then I try to capitalize only words into the condition. One of the conditions is that the first string is capitalized. And it's just the one that is left
我有一根绳子。首先,我将它转换为一个数组,然后尝试只将单词大写到条件中。其中一个条件是第一个字符串是大写的。它就是剩下的那个。
class Book
# write your code her
attr_reader :title
def title=(new_title)
words = new_title.split(" ")
if words.length > 1
final_title = ""
final_title = words.map! {|a| ((a != "and" && a != "the") && a.length > 2) ? a.capitalize : a}
@title = final_title.join(" ")
else
@title = new_title.capitalize
end
end
end
That's what I've done until now.
这就是我现在所做的。
I tried to use each_with_index
but map!
doesn't work with it.
我尝试使用each_with_index但是map!不使用它。
I expected:
我期望:
"To Kill a Mockingbird"
but I got:
但我有:
"to Kill a Mockingbird"
4 个解决方案
#1
3
Since version 1.9.3, Ruby has had Enumerator#with_index. The method map
without a block returns an Enumerator
, so you can do the following:
自1.9.3版本以来,Ruby已经有了Enumerator#with_index。没有块的方法映射返回一个枚举数,因此可以执行以下操作:
final_title = words.map.with_index do |word, i|
if i != 0 && (word == "and" || word == "the" || word.length < 3)
word.downcase
else
word.capitalize
end
end
Clearly, you should make sure your title is lowercase to begin with, or the code checking for "and" and "the" won't work.
显然,您应该确保您的标题以小写开头,或者检查“and”和“the”的代码不起作用。
#2
8
I'd start by separating the first word from the remaining words:
我先把第一个单词和剩下的单词分开:
first, *rest = new_title.split(' ')
Then I would capitalize the first word:
然后我将第一个词大写:
first.capitalize!
Afterwards, I would capitalize each remaining word matching the conditions:
之后,我会把每一个与条件匹配的词大写:
rest.select { |w| w != 'and' && w != 'the' && w.length > 2 }.each(&:capitalize!)
And finally put everything back together:
最后把所有的东西都重新放在一起:
[first, *rest].join(' ')
#3
2
You can map over an array with an index, but you have to do it like this:
你可以用一个索引映射一个数组,但是你必须这样做:
class Book
attr_reader :title
def title=(new_title)
words = new_title.split
final_title = words.map.with_index { |word, i| primary_word?(word) || i == 0 ? word.capitalize : word }
@title = final_title.join(' ')
end
def primary_word?(word)
((word != 'and' && word != 'the') && word.length > 2)
end
end
For clarity, I also extracted the logic for determining if a word should be capitalized into its own method.
为了清晰起见,我还提取了一个逻辑,用于确定一个单词是否应该大写到它自己的方法中。
#4
2
Here's a much shorter version, using gsub
with block :
这里有一个更短的版本,使用gsub与block:
- It works with any case as input
- 它可以在任何情况下作为输入
- It checks directly in the regex if the word has at least 3 characters
- 如果单词至少有3个字符,则直接在regex中进行检查。
- It uses capitalize on
new_title
: that way, the first word is capitalized and all the others are lowercase before the processing. - 它使用了大写的new_title:这样,第一个词就大写了,所有其他的在处理之前都是小写的。
Here's the method :
这是方法:
OMIT_CAPITALIZE = %w(the and)
new_title.capitalize.gsub(/\S{3,}/) do |word|
OMIT_CAPITALIZE.include?(word) ? word : word.capitalize
end
Here's a way to integrate it into your class. title
has been added as a parameter to initialize
for easier use of Book
:
这是一种将它集成到类中的方法。添加标题作为参数进行初始化,便于图书使用:
class Book
OMIT_CAPITALIZE = %w(the and)
attr_reader :title
def initialize(title)
self.title = title
end
def title=(new_title)
@title = new_title.capitalize.gsub(/\S{3,}/) do |word|
OMIT_CAPITALIZE.include?(word) ? word : word.capitalize
end
end
end
puts Book.new('to kill a mockingbird').title
# To Kill a Mockingbird
puts Book.new('ThE beauty and THE beast').title
# The Beauty and the Beast
puts Book.new('TO BE OR NOT TO BE').title
# To be or Not to be
#1
3
Since version 1.9.3, Ruby has had Enumerator#with_index. The method map
without a block returns an Enumerator
, so you can do the following:
自1.9.3版本以来,Ruby已经有了Enumerator#with_index。没有块的方法映射返回一个枚举数,因此可以执行以下操作:
final_title = words.map.with_index do |word, i|
if i != 0 && (word == "and" || word == "the" || word.length < 3)
word.downcase
else
word.capitalize
end
end
Clearly, you should make sure your title is lowercase to begin with, or the code checking for "and" and "the" won't work.
显然,您应该确保您的标题以小写开头,或者检查“and”和“the”的代码不起作用。
#2
8
I'd start by separating the first word from the remaining words:
我先把第一个单词和剩下的单词分开:
first, *rest = new_title.split(' ')
Then I would capitalize the first word:
然后我将第一个词大写:
first.capitalize!
Afterwards, I would capitalize each remaining word matching the conditions:
之后,我会把每一个与条件匹配的词大写:
rest.select { |w| w != 'and' && w != 'the' && w.length > 2 }.each(&:capitalize!)
And finally put everything back together:
最后把所有的东西都重新放在一起:
[first, *rest].join(' ')
#3
2
You can map over an array with an index, but you have to do it like this:
你可以用一个索引映射一个数组,但是你必须这样做:
class Book
attr_reader :title
def title=(new_title)
words = new_title.split
final_title = words.map.with_index { |word, i| primary_word?(word) || i == 0 ? word.capitalize : word }
@title = final_title.join(' ')
end
def primary_word?(word)
((word != 'and' && word != 'the') && word.length > 2)
end
end
For clarity, I also extracted the logic for determining if a word should be capitalized into its own method.
为了清晰起见,我还提取了一个逻辑,用于确定一个单词是否应该大写到它自己的方法中。
#4
2
Here's a much shorter version, using gsub
with block :
这里有一个更短的版本,使用gsub与block:
- It works with any case as input
- 它可以在任何情况下作为输入
- It checks directly in the regex if the word has at least 3 characters
- 如果单词至少有3个字符,则直接在regex中进行检查。
- It uses capitalize on
new_title
: that way, the first word is capitalized and all the others are lowercase before the processing. - 它使用了大写的new_title:这样,第一个词就大写了,所有其他的在处理之前都是小写的。
Here's the method :
这是方法:
OMIT_CAPITALIZE = %w(the and)
new_title.capitalize.gsub(/\S{3,}/) do |word|
OMIT_CAPITALIZE.include?(word) ? word : word.capitalize
end
Here's a way to integrate it into your class. title
has been added as a parameter to initialize
for easier use of Book
:
这是一种将它集成到类中的方法。添加标题作为参数进行初始化,便于图书使用:
class Book
OMIT_CAPITALIZE = %w(the and)
attr_reader :title
def initialize(title)
self.title = title
end
def title=(new_title)
@title = new_title.capitalize.gsub(/\S{3,}/) do |word|
OMIT_CAPITALIZE.include?(word) ? word : word.capitalize
end
end
end
puts Book.new('to kill a mockingbird').title
# To Kill a Mockingbird
puts Book.new('ThE beauty and THE beast').title
# The Beauty and the Beast
puts Book.new('TO BE OR NOT TO BE').title
# To be or Not to be