LoginSignup
9
5

More than 5 years have passed since last update.

inject(:merge)で配列内のhashを結合する

Last updated at Posted at 2017-04-13

はじめに

先日友人から以下のようなリクエストをうけました。

[{0=>{:number=>1}}, {1=>{:number=>2}}, {2=>{:number=>3}}]

これを

{0=>{:number=>1}, 1=>{:number=>2}, 2=>{:number=>3}}

こんな感じに変換するいい感じの方法って何かありますかね??

どういう状況でこんな形になったんだろうと思いつつも、なかなか面白い頭の体操だと思い取り組んでみました。
※ hashの中身は適当です。

解答例

解答1

ゴリゴリ頑張る。eachで頑張ります。

hash = {}
[{0=>{:number=>1}}, {1=>{:number=>2}}, {2=>{:number=>3}}].each do |h|
  hash.merge!(h)
end

hash
=> {0=>{:number=>1}, 1=>{:number=>2}, 2=>{:number=>3}}

解答2

Hash[X.map(&:flatten)]を使う。一回配列にしてhashに戻す方法ですね。

Hash[[{0=>{:number=>1}}, {1=>{:number=>2}}, {2=>{:number=>3}}].map(&:flatten)]
=> {0=>{:number=>1}, 1=>{:number=>2}, 2=>{:number=>3}}

自分の解答

inject(:merge)を使う方法が思いつきました。(またはinject(&:merge))

[{0=>{:number=>1}}, {1=>{:number=>2}}, {2=>{:number=>3}}].inject(:merge)
=> {0=>{:number=>1}, 1=>{:number=>2}, 2=>{:number=>3}}

inject(:+)はよく使用するのでそれを応用してinject(:merge)も配列の要素内のhashを結合するのに使えるのではという発想です。

もし仮に(ないとは思いますが)同じキーを持った値があったときは上書きされてしまうので注意が必要ですね。

[{0=>{:number=>1}}, {1=>{:number=>2}}, {2=>{:number=>3}}, {0=>{:number=>4}}].inject(:merge)
=> {0=>{:number=>4}, 1=>{:number=>2}, 2=>{:number=>3}}
9
5
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
9
5