2015-04-24 1 views
0

Я пытаюсь получить хэш, который имеет массив значений, инвертированных таким образом, что теперь ключи являются значениями. Из выражения, как это:Инвертирование хэша: создание нескольких хеш-ключей из массива

StackOverflow.transform({ 1 => ['A', 'E'] , 2 => ["B"]}) 

Я пытаюсь получить этот результат:

{"A"=>1, "E"=>1, "B"=>2} 

У меня есть это:

class StackOverflow 
    def self.transform(old) 
    a = Hash[old.map { |k,v| v.product([k]) }.first] 
    end 
end 

но ключи все разделены, как отдельные клавиши (не сгруппированы). Она возвращает:

{"A"=>1, "E"=>1} 

Я также пытаюсь downcase ключей, но я чувствую, что после того, как я выясняю этот вопрос инверсии правильно, я буду в состоянии (надеюсь?) Фигура из логики downcasing а ,

+0

Я предпочитаю @ использование Марка из 'flat_map', но другой вариант заключается в замене' 'first' с расплющить (1)'. –

+0

Это дубликат http://stackoverflow.com/questions/7513730/hash-invert-in-ruby, хотя, возможно, стоит оставить его с тех пор, как @MarkThomas имеет лучший ответ, чем любой, что я видел в предыдущем вопросе? – Sid

+0

Это очень похоже @Sid, но, к сожалению, я не смог найти хороший ответ, который имел для меня смысл для моей ситуации. Спасибо, что оставили это. К сожалению, я получил пониженное голосование (возможно, за это), но я заверяю людей, что я ищу StackO настолько, насколько это возможно, перед тем, как отправить вопрос. –

ответ

4

Вы были очень близки. Вы хотите использовать flat_map вместо first.

class StackOverflow 
    def self.transform(old) 
    Hash[old.flat_map { |k,v| v.product([k]) }] 
    end 
end 

Вы использовали first выравниваться массив.

0

Другой способ:

class StackOverflow 
    def self.transform(old) 
    val = nil 
    old.each_with_object(Hash.new { |h,k| h[k]=val }) do |(k,v),h| 
     val = k 
     h.values_at(*v) 
    end 
    end 
end 

old = { 1=>['A', 'E'], 2=>['B'] } 
StackOverflow.transform(old) 
    #=> {"A"=>1, "E"=>1, "B"=>2} 
Смежные вопросы