Объединить два массива в хэш - PullRequest
55 голосов
/ 03 марта 2011

У меня есть два массива:

members     = ["Matt Anderson", "Justin Biltonen", "Jordan Luff", "Jeremy London"]
instruments = ["guitar, vocals", "guitar", "bass", "drums"]

Что я хотел бы сделать, так это объединить их так, чтобы полученная структура данных представляла собой хеш-код, например:

{"Matt Anderson"=>["guitar", "vocals"], "Justin Biltonen"=>"guitar", "Jordan Luff"=>"bass", "Jeremy London"=>"drums"}

Обратите внимание, что значение для "Matt Anderson" теперь представляет собой массив вместо строки. Любые волшебники Руби хотят дать этому шанс?

Я знаю, Hash[*members.zip(instruments).flatten] объединяет их почти так, как я хочу, но как насчет того, чтобы сначала превратить строку "гитары, вокал" в массив? Спасибо.

Ответы [ 7 ]

103 голосов
/ 04 февраля 2012

Как писал Рэйф Кеттлер, использование zip - это путь.

Hash[members.zip(instruments)] 
45 голосов
/ 03 марта 2011

Используйте map и split для преобразования строк инструмента в массивы:

instruments.map {|i| i.include?(',') ? (i.split /, /) : i}

Затем используйте Hash[] и zip для объединения members с instruments:

Hash[members.zip(instruments.map {|i| i.include?(',') ? (i.split /, /) : i})]

для получения

{"Jeremy London"=>"drums",
 "Matt Anderson"=>["guitar", "vocals"],
 "Jordan Luff"=>"bass",
 "Justin Biltonen"=>"guitar"}

Если вам все равно, списки из одного элемента также являются массивами, вы можете использовать это более простое решение:

Hash[members.zip(instruments.map {|i| i.split /, /})]

, котороедает вам это:

{"Jeremy London"=>["drums"],
 "Matt Anderson"=>["guitar", "vocals"],
 "Jordan Luff"=>["bass"],
 "Justin Biltonen"=>["guitar"]}
8 голосов
/ 12 октября 2012

Пример 01

k = ['a', 'b', 'c']
v = ['aa', 'bb']
h = {}

k.zip(v) { |a,b| h[a.to_sym] = b } 
# => nil

p h 
# => {:a=>"aa", :b=>"bb", :c=>nil}

Пример 02

k = ['a', 'b', 'c']
v = ['aa', 'bb', ['aaa','bbb']]
h = {}

k.zip(v) { |a,b| h[a.to_sym] = b }
p h 
# => {:a=>"aa", :b=>"bb", :c=>["aaa", "bbb"]}
3 голосов
/ 20 августа 2014

Это лучший и самый чистый способ делать то, что вы хотите.

Hash[members.zip(instruments.map{|i| i.include?(',') ? i.split(',') : i})]

Наслаждайтесь!

1 голос
/ 03 марта 2011
members.inject({}) { |m, e| t = instruments.delete_at(0).split(','); m[e] = t.size > 1 ? t : t[0]; m }

Если в результате вы не заботитесь о массивах из 1 элемента, вы можете использовать:

members.inject({}) { |m, e| m[e] = instruments.delete_at(0).split(','); m }
1 голос
/ 03 марта 2011
h = {}
members.each_with_index do |el,ix|
    h[el] = instruments[ix].include?(",") ? instruments[ix].split(",").to_a : instruments[ix]
end
h
0 голосов
/ 03 марта 2011
h = {}

members.each_with_index {|item, index|
     h.store(item,instruments[index].split)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...