2013-03-07 2 views
0

Мой Хеш:реверса хэш и слияние ключей в рубин

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

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

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

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

+0

думаю, что люди попытаются использовать ваш пример для тестирования, дать хэш со значениями, а не переменными или заполнителями. – tokland

+0

отредактировал его так, чтобы он использовал строки, я думаю, что это лучше, чем использование более сложных объектов. –

+1

Хорошо, это также может помочь показать код, чтобы увидеть, где вы находитесь. Я думаю, у вас есть рабочий код, но он не удовлетворен решением. – tokland

ответ

3
res = {} 
h.each{|k, v| v.each{|vv| res[vv] ||= []; res[vv].push(k)}} 
2

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

require 'facets' 
h.flat_map { |k, vs| vs.product([k]) }.map_by { |k, v| [k, v] } 
#=> {"x"=>["a", "b"], "y"=>["a"], "z"=>["b"]} 
+0

любая идея, почему я получаю 'NoMethodError: undefined method 'map_by' для [[" x "," a "], [" y "," a "], [" x "," b "], [" z "," b "]]: Array' –

+0

' require 'facets'' – tokland

0

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

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

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

Смежные вопросы