如何使数组中的第一个元素在Ruby中大写?

时间:2022-06-16 16:52:18

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