Reputation: 11
The following code is intended to capitalize the first letter of each word in a string, and it works:
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"
I do not understand why it works. In the while
loop, I did not set any element in the words
array to anything new. I understand that it might work if I added the following line before the index iteration:
words[idx] = word
I would then be altering the elements of words
. However, the code works even without that line.
Upvotes: 0
Views: 702
Reputation: 160611
You're doing a lot of work that you don't have to:
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"
Breaking it down:
'foo'[0] # => "f"
'foo'[0].upcase # => "F"
'foo'[1..-1] # => "oo"
['F', 'oo'].join # => "Foo"
Upvotes: 0
Reputation: 2051
yet in no place in the while loop that I am using to capitalize the first letter of each word do I actually set any of the elements in the "words" array to anything new.
You do, actually, right here:
word = words[idx]
word[0] = word[0].upcase # This changes words[idx][0]!
The upcase
method does just that: returns the upcase
of a given string. For example:
'example'.upcase
# => "EXAMPLE"
'example'[0].upcase
# => "E"
Upvotes: 2
Reputation: 168239
The method String#[]=
that you are using in:
word[0] = ...
is not variable assignment. It alters the content of the receiver string at the given index, retaining the identity of the string as an object. And since word
is not a copy but is the original string taken from words
, in turn, you are modifying words
.
Upvotes: 0