为什么加入不会在每个声明中起作用

时间:2015-02-06 00:30:57

标签: ruby

我试图编写一个方法,将字符串中每个单词的第一个字母大写。

def capitalize(string)
  arr1 = string.split(" ")
  arr2 = []
  arr1.each do |i|
    arr2 << i.split(//)
  end
  arr2.each do |i|
    i[0].upcase!
    i = i.join
  end
  arr2.join(" ")
end

在我的第二个each声明中,每个单词的第一个字母成功大写,我得到这样的内容:

[["A", "a", "a"], ["A", "a", "a", "a"]]

我想将每个单词连接在一起,但是i = i.join什么也没做,i.join!抛出一个错误,未定义的方法。我测试了["A", "a", "a"].join,这会产生预期的结果。我很困惑为什么这不适合我的方法,特别是当upcase有效时,这并不是。

你能解释一下我的想法在这种情况下是怎么回事以及如何解决它吗?

2 个答案:

答案 0 :(得分:3)

这里的关键是你在i块内部尝试修改each,但由于i是一个局部变量,它对原始变量没有影响。

你想要的是:

arr2.collect! do |i|
  i[0].upcase!
  i.join
end

这会重写数组的内容。

但是,您可以做的是将其转换为简单的gsub

def capitalize(string)
  string.gsub(/\b([a-z])\B/) do |m|
    $1.upcase
  end
end

答案 1 :(得分:0)

我相信这段代码:

arr1.each do |i|
    arr2 << i.split(//)
end

您正在从第一个数组中分割每个单词的每个字符。这基本上会给你一个数组的数组。如果在第二次循环后放入此块,则可以看到结构:

arr2.each do |i|
    puts("[")
        i.each do |x|
            puts(x)
        end
        puts("]")
end

对于解决方案,可以这样做:

def self.capitalizeB(string)
    return string.split(" ").each { |i| i[0] = i[0].upcase }.join(" ")
end