さて、いくつかの休日(たとえば、fourth_of_july)に見られるように、アンダースコアを削除しようとしています。次に、各単語を大文字にします。
期待される結果:fourth_of_july> 7月4日
これが私のコードです:
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)
このワンライナーを使用できます
str.split('_').map(&:capitalize).join(' ')
これは文字列str
を取り、それを下線がある場所で分割し、各単語を大文字にしてから、単語をスペースで結合します。例
"fourth_of_july".split('_') -> ["fourth", "of", "july"]
["fourth", "of", "july"].map(&:capitalize) -> ["Fourth", "Of", "July"]
["Fourth", "Of", "July"].join(' ') -> "Fourth Of July"
Railsでは、titleize
を使用できます
'fourth_of_july'.titleize => "Fourth Of July"
再帰を使用して、ネストされたハッシュを調べ、すべてのキーを見つけて、変更を適用できます。
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"]}
#}
それはあなたが求めたものではありませんが(答えた後にのみ実現します)、それでもあなたが役に立つと思うので、この答えは残しておきます。
アンダースコア付きの文字列をよりクラス名に似たものに変更する方法を探してここに来ました。 Rails has String#classify
。
irb> 'some_class_string'.classify
=> "SomeClassString"
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"]}}
s[0]=s[0].upcase; s
ではなくs.capitalize
を使用しました。後者は、最初の文字の後のすべての文字を小文字に変換するためです(また、最初の文字を大文字にします)が、質問者はそれが望ましいとは言いませんでした。各単語の最初の文字の後の大文字である。