別記事へのコメント：1つのキーに複数の値が対応して且つそれぞれの値が重複しているハッシュのキーと値を入れ替えたい時のメソッド(Ruby)

#きっかけ
@maoringo さんの

* [1つのキーに複数の値が対応して且つそれぞれの値が重複しているハッシュのキーと値を入れ替えたい時のメソッド(Ruby) - Qiita](http://qiita.com/maoringo/items/ceb2719faec999682b0b)

へのコメントとしての記事です。
本当はコメント欄へ書くつもりだったのですが、わりと充実してしまったので別記事として投稿しましたw
##目的のメソッドの実例
```ruby
#もとのHash
 {"akan"=>["10", "201"], "areha"=>["201"], "okashi"=>["303", "201", "10"]}
#入れ替え後
=> {"10"=>["akan", "okashi"], "201"=>["akan", "areha", "okashi"], "303"=>["okashi"]}
```
#書き替え方針
もとの記事で気になった点

* インデント
* スペース
* ブロックパラメータ`youso`（他が英語に類する単語なので気になる）
* Hash#eachのブロックパラメータ`elem`（つまりキーが`elem[0]`で値が`elem[1]`）をブロック内でそのまま`elem[0]`および`elem[1]`として用いている
* 複数の値（具体的には配列）が1要素の場合に、開き方が`elem[1].join("")`

を直したくなり、メソッドの書換を試みました。また
>値が配列の形じゃないとこのメソッド使えないです。ごめんなさい。

とのことだったので、その点に関してもいじれないか（具体的にはEnumerableが使えるように）頑張ってみました。
#書き替え後のメソッド
```ruby
def safe_invert_d_hash(orig_hash)
  orig_array = []
  orig_hash.each_pair{ |k, item|
    if item.count > 1
      item.each{ |itm|
        orig_array << [itm, k]
      }
    else
      orig_array << [item.first, k]
    end
  } 
  result = Hash.new{ |h, key| h[key] = [] }
  orig_array.each{ |key, value|
    result[key] << value
  }
  result
end
```
##ポイント
* ブロックパラメータの名前（とはいえこれも適当ですが）
* `each`のレシーバがHashクラスだということを明示するために`Hash#each_pair`で表記しました。これで、ブロックパラメータがペア（2個）でない場合には、おかしいと直ぐ気付けます。
* `Array#length`の代わりに`Enumerable#count`を使いました。同様に値の要素が一つだけの場合は`Enumerable#first`で値を取得しています。
* 元の記事では「値の要素数が1以外ならば」でしたが、つまりは「値の要素数が1より多いならば」なので不等号にしました。（個人的に、等号に類するものは代入と書き間違えるおそれがあるので、出来るだけ使わないようにしています。）

本当ならば、複数行のブロック部分を`{…}`ではなく`do…end`にしたいのですが、今回はやめておきました。
##`safe_invert_d_hash`の動作確認その１
```ruby
h = {"akan"=>["10", "201"], "areha"=>["201"], "okashi"=>["303", "201", "10"]}
# => {"akan"=>["10", "201"], "areha"=>["201"], "okashi"=>["303", "201", "10"]}
safe_invert_d_hash(h)
# => {"10"=>["akan", "okashi"], "201"=>["akan", "areha", "okashi"], "303"=>["okashi"]}
```
問題ないようです。
#Enumerableでも動くか
複数以外の要素を持つオブジェクトを一般化すれば、だいたいEnumerableに含まれると思います。ので、Enumerableを対象にします。
##準備
適当なEnumerableを思いつかなかったので、非常にくだらないReversePushArrayクラスを作りましたw オブジェクトに`<<`すると、内部で逆並び配列に要素が詰め込まれていく、というものです。要素追加の`ReversePushArray#<<`以外のメソッドは、内部を見る`ReversePushArray#to_a`とEnumerableにするための`ReversePushArray#each`のみw
要素を消すことも、要素の一部を見ることも出来ませんw でも`each`が定義されて`include Enumerable`されているのでEnumerableです。

```ruby
class ReversePushArray
  include Enumerable
  def initialize(init = [])
    @items = init.reverse
  end
  
  def <<(i)
   @items.unshift i
  end
  
  def to_a
    @items
  end
  
  def each
    @items.each do |item|
      yield(item)
    end
  end
end
```

さて、このクラス、てきとーなのでインスタンス作るのも面倒ですw 当初は`def initialize; @items = []; end`と書いていて、いちいちインスタンスに`<<`で要素をツッコんでいましたが、本当に面倒になってきたので上記に書き替えましたw
##要素作成
```ruby
ra4 = ReversePushArray.new([1, 2, 4, 8, 16])
# => #<ReversePushArray:0x007fa5a9b2b6b8 @items=[16, 8, 4, 2, 1]>
ra4.to_a
# => [16, 8, 4, 2, 1]
```
EnumerableをIncludeしているので、既にいろんなメソッドが使えます。

```ruby
ra4.map{|i| 2 ** i}
# => [65536, 256, 16, 4, 2]
```
##`safe_invert_d_hash`の動作確認その２
ではこのインスタンス`ra4`を使って、先ほどのメソッド`safe_invert_d_hash`が働くか確認します。

```ruby
h = {ra: ra4, arr: [8, 2, 6]}
# => {:ra=>#<ReverseArray:0x007fa5a920a228 @items=[16, 8, 4, 2, 1]>, :arr=>[8, 2, 6], empty: []}
safe_invert_d_hash(h)
# => {16=>[:ra], 8=>[:ra, :arr], 4=>[:ra], 2=>[:ra, :arr], 1=>[:ra], 6=>[:arr] nil=>[:empty]}
```
動いていますね。
個人的には（配列のような）位置を指定して要素にアクセスする機能の **無い** オブジェクトであっても扱えるのがポイントです。
あまり試していませんので、問題あればご連絡下さい。また考えます。