views:

174

answers:

5

Hi All I recently was challenged to write some Ruby code to change the last character of every word in a sentence into a capital. Such that the string:

  "script to convert the last letter of every word to a capital"
  becomes
  "scripT tO converT thE lasT letteR oF everY worD tO A capitaL"

This was my optimal solution however I'm sure you wizards have much better solutions and I would be really interested to hear them.

  "script to convert the last letter of every word to a capital".split.map{|w|w<<w.slice!(-1).chr.upcase}.join' '

For those interested as to what is going on here is an explanation.

split will split the sentence up into an array, the default delimiter is a space and with Ruby you don't need to use brackets here.

map the array from split is passed to map which opens a block and process each word (w) in the array. the block slice!(s) off the last character of the word and converts it to a chr (a character not ASCII code) and then capitalises upcase it. This character is now appended << to the word which is missing the sliced last letter. Finally the array of words is now join together with a ' ' to reform the sentence.

Enjoy

+8  A: 

here's a quick and dirty regex method that's sure to be broken in ways I haven't considered:

"the quick brown fox jumps over the lazy dog".gsub(/.\b/) { |m| m.upcase }

i.e. upcase the last character match before a word boundary.

x1a4
This is actually better than the original because it doesn't fail for non-space word boundaries.
molf
The only problem I can find with this is inter-word punctuation, like apostrophes in contractions (eg. "don't").
mckeed
@mckeed Good call. I knew something was missing.
x1a4
Very good much better.
emson
+1  A: 

My attempt at covering all the punctuation issues with a regexp:

str = %("But we're street-smart," she said.)

str.gsub(/\w\W*(\s|$)/) {|m| m.upcase }
mckeed
+1  A: 
str.reverse.split(/\b/).map(&:capitalize).join.reverse

However, it downcases all other letters...

hurikhan77
+4  A: 

With rails titleize method you could:

str.reverse.titleize.reverse
samuil
brilliant! (i suppose that was the intent of the original question)
Nas Banov
Cool I was trying to think of a way using reverse, shame that titleize isn't a Ruby command... but there weren't really any rules anyway.
emson
+2  A: 

Well i don't know Ruby but here is attempt in its cousin (Python), it's even a bit shorter:

' '.join(w[:-1]+w[-1].upper()for w in
"script to convert the last letter of every word to a capital".split())

But the approach with reverse-titleize-reverse is the real deal:

"script to convert the last letter of every word to a capital"[::-1].title()[::-1]
Nas Banov
Great like your thinking.
emson