Реверсирование хеша и слияние ключей в ruby

Мой хэш:

h = { 'a' => ['x' ,'y'], 'b' => ['x','z']}

Я хочу поменять местами ключи и значения и объединить новые ключи таким образом, чтобы

 res = { 'x' => ['a','b'], 'y' => ['a'], 'z' => ['b']}

Есть ли способ сделать это?


person Nick Ginanto    schedule 07.03.2013    source источник
comment
думайте, что люди попытаются использовать ваш пример для тестирования, дайте хэш со значениями, а не переменными или заполнителями.   -  person tokland    schedule 07.03.2013
comment
отредактировал его так, чтобы он использовал строки, я думаю, что это лучше, чем использование более сложных объектов   -  person Nick Ginanto    schedule 07.03.2013
comment
Хорошо, это также может помочь показать код, чтобы увидеть, где вы находитесь. Я думаю, у вас есть рабочий код, но вы не удовлетворены решением.   -  person tokland    schedule 07.03.2013


Ответы (2)


Функциональный подход с использованием Enumerable#map_by из Facets:

require 'facets'
h.flat_map { |k, vs| vs.product([k]) }.map_by { |k, v| [k, v] }
#=> {"x"=>["a", "b"], "y"=>["a"], "z"=>["b"]}
person tokland    schedule 07.03.2013
comment
есть идеи, почему я получаю NoMethodError: undefined method 'map_by' for [["x", "a"], ["y", "a"], ["x", "b"], ["z", "b"]]:Array - person Nick Ginanto; 07.03.2013

Попробуй это..

rev = {}
h.collect{|k, v| v.each{|vv| rev.has_key?(vv)? rev[vv] << k : (rev[vv] = [k])}}

Я протестировал его, он работает.

person Ramiz Raja    schedule 07.03.2013