結局、ボヘミアン・ラプソディ見なかったので、せめてQeenの前身となったSmileのhashの中身を入れ替えて、Queenのhashにしてみました。
each_with_objectとinjectを使って、Smileのhashから、vocal、bassを務めるティム・スタッフェルの代わりにフレディ・マーキュリーとジョン・ディーコンを加えてQueenのhashを新たに作ります。
* 2019/2/27追記
コメント欄にて@QUANONさんからコメント頂いたので追記です!
今回のようなhashの入れ替えは、Hash#mergeを使うのが一般的とアドバイス頂きました。
smile = { vocal: 'tim', guitar: 'brian', bass: 'tim', drum: 'roger' }
queen = smile.merge(vocal: 'fleddie', bass: 'jhon')
=> {:vocal=>"fleddie", :guitar=>"brian", :bass=>"jhon", :drum=>"roger"}
以下に書いてるようにループで面倒な事してましたね。勉強になりました!
each_with_object
old_hash.each_with_object(初期化object) {|item, new_hash| block処理 }
初期化オブジェクトに{}を入れてhashにし、itemに(key、value)を入れてnew_hashに1つずつ入れるblock処理にします。
smile = { vocal:'tim', guitar:'brian', bass:'tim', drum:'roger' }
queen = smile.each_with_object({}) do |(key, val), member|
member[key.to_sym] =
case key
when :vocal
member[:vocal] = 'fleddie'
when :bass
member[:bass] = 'jhon'
else
val
end
end
inject
old_hash.inject(初期化object) {|new_hash, item| block処理 }
smile = { vocal:'tim', guitar:'brian', bass:'tim', drum:'roger' }
queen = smile.inject({}) do |member, (key, val)|
member[key.to_sym] =
case key
when :vocal
member[:vocal] = 'fleddie'
when :bass
member[:bass] = 'jhon'
else
val
end
member #injectの場合、ブロックでループする最後に作成中のhashを返す行が必要
end
例題はふざけてますが、元のhashを加工して違うhashとして使用する事って、たまにあると思います。