Объедините два массива в хэш
У меня есть два массива:
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" теперь представляет собой массив вместо строки. Любые мастера Ruby могут сделать это?
Я знаю, что Hash[*members.zip(instruments).flatten]
объединяет их почти так, как я хочу, но как насчет того, чтобы сначала включить строку "гитары, вокал" в массив? Спасибо.
Ответы
Ответ 1
Используйте 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"]}
Ответ 2
Как сказал Рейф Кеттлер, использование zip - это путь.
Hash[members.zip(instruments)]
Ответ 3
Пример 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"]}
Ответ 4
Это лучший и самый чистый способ сделать то, что вы хотите.
Hash[members.zip(instruments.map{|i| i.include?(',') ? i.split(',') : i})]
Наслаждайтесь!
Ответ 5
h = {}
members.each_with_index do |el,ix|
h[el] = instruments[ix].include?(",") ? instruments[ix].split(",").to_a : instruments[ix]
end
h
Ответ 6
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 }
Ответ 7
h = {}
members.each_with_index {|item, index|
h.store(item,instruments[index].split)
}