如何只在Ruby中使用数组的第一个元素

时间:2017-03-23 12:22:05

标签: ruby

我被给了一个字符串。首先,我将它转换为数组,然后我尝试只将单词大写到条件中。其中一个条件是第一个字符串是大写的。 而它只是留下的那个

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

这是我迄今为止所做的。

我尝试使用each_with_index,但map!无法使用它。

我期待:

"To Kill a Mockingbird"

但我得到了:

"to Kill a Mockingbird"

5 个答案:

答案 0 :(得分:8)

我首先将第一个单词与其余单词分开:

first, *rest = new_title.split(' ')

然后我会把第一个词大写:

first.capitalize!

之后,我会将符合条件的每个剩余单词大写:

rest.select { |w| w != 'and' && w != 'the' && w.length > 2 }.each(&:capitalize!)

最后把所有东西放回原处:

[first, *rest].join(' ')

答案 1 :(得分:3)

从版本1.9.3开始,Ruby已经有Enumerator#with_index。没有块的方法map会返回Enumerator,因此您可以执行以下操作:

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

显然,您应该确保您的标题首先是小写,否则检查“and”和“the”的代码将无效。

答案 2 :(得分:2)

您可以使用索引映射数组,但必须这样做:

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

为了清楚起见,我还提取了逻辑,以确定一个单词是否应该大写成自己的方法。

答案 3 :(得分:2)

这是一个更短的版本,使用gsub with block

  • 适用于任何情况作为输入
  • 直接在正则表达式中检查单词是否至少包含3个字符
  • 它使用new_title上的大写:这样,第一个单词大写,其他所有单词在处理前都是小写。

以下是方法:

OMIT_CAPITALIZE = %w(the and)
new_title.capitalize.gsub(/\S{3,}/) do |word|
  OMIT_CAPITALIZE.include?(word) ?  word : word.capitalize
end

这是将它集成到您​​的课程中的一种方法。已将title添加为initialize的参数,以便更轻松地使用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

答案 4 :(得分:0)

string.split(' ').map(&:capitalize).join(' ')