17

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)
Eli Sadoff
  • 7,173
  • 6
  • 33
  • 61
Jun
  • 173
  • 1
  • 1
  • 4

5 Answers5

37

In Rails you can use titleize

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

https://apidock.com/rails/Inflector/titleize

Rahul Patel
  • 1,386
  • 1
  • 14
  • 16
11

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"
Eli Sadoff
  • 7,173
  • 6
  • 33
  • 61
  • 1
    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("_"," ").split(' ').map {|word| word.capitalize }.join(' ')}: #{supplies.join(", ")}" end end end – Jun Nov 17 '16 at 01:00
  • I actually did it that way instead of using the "&". What is the purpose of it? – Jun Nov 17 '16 at 01:00
  • You can use `&` when mapping over something if the map takes no parameters. It's the same thing as `{|i| i.capitalize}`, just shorter. – Eli Sadoff Nov 17 '16 at 01:01
6

I came here looking for a way to modify a string with underscores to be more class-name-like. Rails has String#classify.

irb> 'some_class_string'.classify
=> "SomeClassString"
taylorthurlow
  • 2,953
  • 3
  • 28
  • 42
1

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.

Sagar Pandya
  • 9,323
  • 2
  • 24
  • 35
0
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.

Cary Swoveland
  • 106,649
  • 6
  • 63
  • 100