为什么大写字符串元素的第一个字母会改变数组?

时间:2015-10-01 20:22:09

标签: ruby

以下代码旨在将字符串中每个单词的首字母大写,并且有效:

def capitalize_words(string)
  words = string.split(" ")
  idx = 0
  while idx < words.length
    word = words[idx]
    word[0] = word[0].upcase
    idx += 1
  end
  return words.join(" ")
end

capitalize_words("this is a sentence") # => "This Is A Sentence"
capitalize_words("mike bloomfield") # => "Mike Bloomfield"

我不明白为什么会这样。在while循环中,我没有将words数组中的任何元素设置为任何新元素。我理解如果我在索引迭代之前添加以下行可能会有效:

words[idx] = word

然后我会改变words的元素。但是,即使没有该行,代码也能正常工作。

3 个答案:

答案 0 :(得分:2)

  

但是在我用来大写的while循环中没有任何地方   每个单词的第一个字母我实际上设置了任何元素   &#34;也就是说&#34;数组到任何新的。

实际上,你就在这里:

word = words[idx]
word[0] = word[0].upcase # This changes words[idx][0]!

upcase方法就是这样做:返回给定字符串的upcase。例如:

'example'.upcase
# => "EXAMPLE" 
'example'[0].upcase
# => "E" 

答案 1 :(得分:0)

您正在使用的方法String#[]=

word[0] = ...

不是变量赋值。它改变给定索引处接收器字符串的内容,保留字符串作为对象的标识。由于word不是副本,而是从words获取的原始字符串,因此您正在修改words

答案 2 :(得分:0)

你做了很多你不必做的工作:

def capitalize_words(string)
  string.split.map{ |w|
    [w[0].upcase, w[1..-1]].join # => "Foo", "Bar"
  }.join(' ')
end

capitalize_words('foo bar')
# => "Foo Bar"

打破它:

'foo'[0] # => "f"
'foo'[0].upcase # => "F"
'foo'[1..-1] # => "oo"

['F', 'oo'].join # => "Foo"