Ruby: Titleize: How to Ignore Smaller Words Like 'And', 'The', 'Or, etc

Using title case with Ruby 1.8.7

You could create a list of the word you don't want to capitalize and do

excluded_words = %w(the and in) #etc

def capitalize_all(sentence, excluded_words)
sentence.gsub(/\w+/) do |word|
excluded_words.include?(word) ? word : word.capitalize
end
end

By the way, if you were using Rails and did not need to exclude specific words you could use titleize.

"the catcher in the rye".titleize
#=> "The Catcher In The Rye"

Why do I get a nil after changing the order of two lines?

why do I get nil when I reverse the order of the words.first.capitalize and words.join(" ") lines?

This is the reason:

"abb".capitalize # => "Abb"
"Abb".capitalize! # => nil
"Abb".capitalize # => "Abb"

String.capitalize! says:

Modifies str by converting the first character to uppercase and the remainder to lowercase. Returns nil if no changes are made. Note: case conversion is effective only in ASCII region.

When you are putting the line words.first.capitalize! at the end of your method, the String.capitalize! tried to capitalize the word which is already capitalized. You are using the bang(!) version, so, as per the documentation, you are getting nil.

One example:

def titleize(x)
words = x.split(" ").collect do |word|
if %w(the and of).include?(word)
word
else
word.capitalize
end
end

words.join(" ")
words.first.capitalize!
end

titleize("he great book") # => nil

Probably your input string was not containing any of the words you listed here %w(the and of), when you were testing. I would recommend you to use String#capitalize instead.

Modifying an array item in Ruby if it includes a specific word

I like to break these types of problems up into smaller chunks of logic to help me understand before I write an algorithm. In this case you need to modify each word of the string based on some rules.

  1. If it's the first word, capitalize it.
  2. If it's not a special word, capitalize it.
  3. If it's a special word AND it's not the first word, downcase it.

With these rules you can write your logic to follow.

special_words = ['a', 'an', 'and', 'of', 'the']
fixed_words = []
@string.downcase.split.each_with_index do |word, index|
# If this isn't the first word, and it's special, use downcase
if index > 0 and special_words.include?(word)
fixed_words << word
# It's either the first word, or not special, so capitalize
else
fixed_words << word.capitalize
end
end
fixed_words.join(" ")

You'll notice I'm using downcase on the string before calling split and each_with_index. This is so that all the words get normalized a downcase and can be easily checked against the special_words array.

I'm also storing these transformed words in an array and joining them back together in the end. The reason for that, is if I try to use downcase! or capitalize! on the split strings, I'm not modifying the original title string.

Note: This problem is part of the Bloc Full Stack course work which is why I'm using a simplified solution, rather than one liners, modules, file io, etc.

Ruby on Rails: Converting SomeWordHere to some word here

alt text

The methods underscore and humanize are designed for conversions between tables, class/package names, etc. You are better off using your own code to do the replacement to avoid surprises. See comments.

"SomeWordHere".underscore => "some_word_here"

"SomeWordHere".underscore.humanize => "Some word here"

"SomeWordHere".underscore.humanize.downcase => "some word here"

Capitalize first letter in Ruby with UTF-8 strings with exceptions

"åbc".mb_chars.capitalize
#=> "Åbc"
"ébc".mb_chars.capitalize.to_s
#=> "Ébc"

UPD

And to ignore none word chars:

string = "-åbc"
str = string.match(/^(\W*)(.*)/)
str[1] + str[2].mb_chars.capitalize.to_s
#=> "-Åbc"


Related Topics



Leave a reply



Submit