Ruby - remove underscores and capitalize

Okay so I'm trying to remove the underscores, as seen in some of the holidays (for example,fourth_of_july). Then I want to capitalize each of the words.

Expected result: fourth_of_july > Fourth Of July

so this is my code:

holiday_dec = {

:winter => {
   :christmas => ["Lights", "Wreath"],
   :new_years => ["Party Hats"]
 },
 :summer => {
   :fourth_of_july => ["Fireworks", "BBQ"]
 },
 :fall => {
   :thanksgiving => ["Turkey"]
 },
 :spring => {
   :memorial_day => ["BBQ"]
 }

}

def all_supplies_in_holidays(holiday_hash)

  holiday_hash.each do |seasons, holidays|

    holidays.each do |holidays, supplies|
      puts "#{seasons.to_s.capitalize}:"
      puts "  #{holidays.to_s.tr("_"," ").capitalize}: #{supplies.join(", ")}"
    end

  end

end

all_supplies_in_holidays(holiday_dec)


ANSWERS:


You can use this one liner

str.split('_').map(&:capitalize).join(' ')

This takes a string str and splits it where the underscores are, then capitalizes each word then joins the words together with a space. Example

"fourth_of_july".split('_') -> ["fourth", "of", "july"]
["fourth", "of", "july"].map(&:capitalize) -> ["Fourth", "Of", "July"]
["Fourth", "Of", "July"].join(' ') -> "Fourth Of July"

holiday_dec.each_with_object({}) { |(k,v),h|
  h[k] = v.each_with_object({}) { |(kk,vv),g|
    g[kk.to_s.split('_').map { |s| s[0]=s[0].upcase; s }.join(' ')] = vv } }
  #=> {:winter=>{"Christmas"=>["Lights", "Wreath"], "New Years"=>["Party Hats"]},
  #    :summer=>{"Fourth Of July"=>["Fireworks", "BBQ"]},
  #    :fall=>{"Thanksgiving"=>["Turkey"]},
  #    :spring=>{"Memorial Day"=>["BBQ"]}}

I used s[0]=s[0].upcase; s rather than s.capitalize because the latter converts all characters after the first to lower case (as well as capitalizing the first letter), yet the asker didn't say that was desired or if there could be capital letters after the first character of each word.


Using recursion we can go through your nested hash, find all your keys and apply the change:

def key_changer hash
  hash.map do |k,v|
    [ k.to_s.scan(/[a-zA-Z]+/).map(&:capitalize).join(' '),
      v.class == Hash ? key_changer(v) : v ]
  end.to_h
end

key_changer holiday_dec #=>

#{ "Winter" => { "Christmas"      => ["Lights", "Wreath"],
#                "New Years"      => ["Party Hats"] },
#  "Summer" => { "Fourth Of July" => ["Fireworks", "BBQ"] },
#  "Fall"   => { "Thanksgiving"   => ["Turkey"] },
#  "Spring" => { "Memorial Day"   => ["BBQ"]}
#}

It's not exactly what you asked for (only realised after answering) but I'll leave this answer up nonetheless as you may find it useful.


In Rails you can use titleize

'fourth_of_july'.titleize => "Fourth Of July"



 MORE:


 ? How do I make the first letter of a string uppercase in JavaScript?
 ? How do I make the first letter of a string uppercase in JavaScript?
 ? How do I make the first letter of a string uppercase in JavaScript?
 ? How do I make the first letter of a string uppercase?
 ? How do I make the first letter of a string uppercase?
 ? How do I make the first letter of a string uppercase?
 ? How do I make the first letter of a string uppercase in JavaScript?
 ? How do I capitalize the first letter of each text input in javaScript?
 ? How do I capitalize the first letter of each text input in javaScript?
 ? How do I capitalize the first letter of each text input in javaScript?