LoginSignup
3
3

More than 5 years have passed since last update.

オブジェクトの中身のHashをselectしつつ全体を返したい

Last updated at Posted at 2015-11-18

やりたいこと

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

ほかによい書き方はないですかね・・・(コメントいただければ追記します)

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3