[Ruby]どうしても配列の中身のハッシュを平坦化させたい

# はじめに
**配列とハッシュが混合したもの**を扱う際に、少々手こずったのでメモ程度に書き起こしておく。
結果的に少々泥臭さのあるコードとなってしまった気がするので、より自然で簡潔なものがあれば、ご指摘していただけると助かります。

# 配列の中のハッシュを平坦化
今回躓いていたのは、**配列の中のハッシュの平坦化**
どうにかして、①の配列を②の配列にしたい。

```.rb
# ①の配列
[
  [{"id"=>1}, {"name"=>"Bob", "gender"=>"m", "birthday"=>"2010/01/01"}],
  [{"id"=>5}, {"name"=>"Tom", "gender"=>"m", "birthday"=>"2011/11/01"}],
  [{"id"=>8}, {"name"=>"Alice", "gender"=>"w", "birthday"=>"2012/02/01"}]
]
```

```.rb
# ②の配列
[
  [{"id"=>1, "name"=>"Bob", "gender"=>"m", "birthday"=>"2010/01/01"}],
  [{"id"=>5, "name"=>"Tom", "gender"=>"m", "birthday"=>"2011/11/01"}],
  [{"id"=>8, "name"=>"Alice", "gender"=>"w", "birthday"=>"2012/02/01"}]
]
```

要するに配列の中身のハッシュを平坦化?というか一つのハッシュにするという作業。

# そもそもの目的
そもそもなぜそんなことをする必要が出てくるのかという話から。
`ids`と`details`という２つの配列がある。

```.rb
ids = [
  { 'id' => 1 },
  { 'id' => 5 },
  { 'id' => 8 }
]

details = [
  {
    'name' => 'Bob',
    'gender' => 'm',
    'birthday' => '2010/01/01'
  },
  {
    'name' => 'Tom',
    'gender' => 'm',
    'birthday' => '2011/11/01'
  },
  {
    'name' => 'Alice',
    'gender' => 'w',
    'birthday' => '2012/02/01'
  }
]
```
この２つの配列は１：１で対応していて、レスポンスで返す際には、これらをくっつけた状態で返したい。
※　`id=1`は`Bob`の情報。`id=5`は`Tom`の情報...

そして、最終的に得たい形は次のハッシュと配列の組み合わせであった。
※　`count`は`ids`の数

```.rb
{
  "count"=>3,
  "details"=> [
    {"id"=>1, "name"=>"Bob", "gender"=>"m", "birthday"=>"2010/01/01"},
    {"id"=>5, "name"=>"Tom", "gender"=>"m", "birthday"=>"2011/11/01"},
    {"id"=>8, "name"=>"Alice", "gender"=>"w", "birthday"=>"2012/02/01"}
  ]
}
```
そのため、配列の中身のハッシュを平坦化させるという作業が必要になる。

# 行ったこと
## zipメソッド
zipメソッドは自身の要素と、引数で与えた配列の要素を**同じインデックス同士**で組み合わせた配列を返す。
今回のように同じインデックス同士で1対1対応しているものにもってこいのメソッドである。

```.rb
details_after_zip = ids.zip(details)
#=> [[{"id"=>1}, {"name"=>"Bob", "gender"=>"m", "birthday"=>"2010/01/01"}], [{"id"=>5}, {"name"=>"Tom", "gender"=>"m", "birthday"=>"2011/11/01"}], [{"id"=>8}, {"name"=>"Alice", "gender"=>"w", "birthday"=>"2012/02/01"}]]
```
ここで最初の方で述べた、「配列の中身のハッシュを平坦化したい」という話に繋がる。
次の方法で一応解決はした。
## mergeメソッド
`merge`メソッドは、2つのハッシュを統合するというもの。

```.rb
bob_info = details_after_zip[0]
bob_info[0].merge(bob_info[1])
#=> {"id"=>1, "name"=>"Bob", "gender"=>"m", "birthday"=>"2010/01/01"}
```
このメソッドをループさせて利用する。

```.rb
details_hash_flatten = details_after_zip.map do |d|
  d[0].merge(d[1])
end

#=>[{"id"=>1, "name"=>"Bob", "gender"=>"m", "birthday"=>"2010/01/01"}, {"id"=>5, "name"=>"Tom", "gender"=>"m", "birthday"=>"2011/11/01"}, {"id"=>8, "name"=>"Alice", "gender"=>"w", "birthday"=>"2012/02/01"}]
```

これで準備は整ったので、当初の目的の形にする。

```.rb
{
  'count' => ids.size,
  'detail' => details_hash_flatten
}

#=>{ "count"=>3, "detail"=>[ {"id"=>1, "name"=>"Bob", "gender"=>"m", "birthday"=>"2010/01/01"}, {"id"=>5, "name"=>"Tom", "gender"=>"m", "birthday"=>"2011/11/01"}, {"id"=>8, "name"=>"Alice", "gender"=>"w", "birthday"=>"2012/02/01"}] }
```

# おわりに
`merge`メソッドをループさせるという解決方法をとった。
しかし、もっと良い方法があったのかもしれない。
それこそ「配列の中身のハッシュを平坦化させる」といったものはあるのだろうか。

# 追記
自分で書いていて感じたことではあったのですが、添字の[0]とかはダサいし、あんまり良くはないので避けたいとのご指摘。

reduceメソッド(またはinject)を使用したら、よりクリーンな形に。

```.rb
ids.zip(details).map { |a| a.reduce(&:merge) }
#=> [{"id"=>1, "name"=>"Bob", "gender"=>"m", "birthday"=>"2010/01/01"}, {"id"=>5, "name"=>"Tom", "gender"=>"m", "birthday"=>"2011/11/01"}, {"id"=>8, "name"=>"Alice", "gender"=>"w", "birthday"=>"2012/02/01"}]
```

こっちのが良いですね。