やりたいこと
input
{:one=>1, :two=>{:foo=>"foofoo", :bar=>"barbar", :hoge=>"hogehoge", :moge=> "mogemoge"}}
:two
の中身の :foo
および :bar
以外を切り落とした全体のHash、すなわち
output
{:one=>1, :two=>{:foo=>"foofoo", :bar=>"barbar"}}
を得たい。なるべくスマートに
案1
input[:two]
に対して Hash#select! を使う。
案1
def solve(input)
input[:two].select! { |key, _| %i(foo bar).include? key }
input
end
お、おう・・・
よく読めば分かるのですが、もう少し簡単になりませんかね?
案2
ActiveSupportを導入し、Hash#slice! を使う。
案2
def solve(input)
input[:two].slice!(:foo, :bar)
input
end
条件のブロックが消せました。これでもよいのですが input
が 2回出現していて冗長に思えます。
案3
Object#tap を使い、ブロック内で書き換える。
案3
def solve(input)
input.tap { |i| i[:two].slice!(:foo, :bar) }
end
1行になりました。しかしブロック内で破壊的変更を行っているので、実行結果が想像しにくいです。個人的には案2のほうがベターかと思います。
案x
ほかによい書き方はないですかね・・・(コメントいただければ追記します)