Combina due matrici in Hash

Ho due matrici:

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

Quello che mi piacerebbe fare è combinare questi in modo tale che la struttura dei dati risultante sia un Hash come questo:

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

Nota che il valore di “Matt Anderson” ora è una matrice anziché una stringa. A tutti i maghi di Ruby importa di fare un tentativo?

So che Hash[*members.zip(instruments).flatten] li combina quasi come voglio io, ma per quanto riguarda trasformare la stringa “guitars, vocals” in una matrice prima? Grazie.

Usa map e split per convertire le stringhe dello strumento in array:

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

Quindi usa Hash[] e zip per combinare i members con gli instruments :

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

ottenere

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

Se non ti interessa se gli elenchi di articoli singoli sono anche matrici, puoi usare questa soluzione più semplice:

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

che ti dà questo:

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

Come ha scritto Rafe Kettler, usare la zip è la strada da percorrere.

 Hash[members.zip(instruments)] 

Esempio 01

 k = ['a', 'b', 'c'] v = ['aa', 'bb'] h = {} k.zip(v) { |a,b| h[a.to_sym] = b } # => nil ph # => {:a=>"aa", :b=>"bb", :c=>nil} 

Esempio 02

 k = ['a', 'b', 'c'] v = ['aa', 'bb', ['aaa','bbb']] h = {} k.zip(v) { |a,b| h[a.to_sym] = b } ph # => {:a=>"aa", :b=>"bb", :c=>["aaa", "bbb"]} 

Questo è il modo migliore e più pulito per fare ciò che vuoi.

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

Godere!

 h = {} members.each_with_index do |el,ix| h[el] = instruments[ix].include?(",") ? instruments[ix].split(",").to_a : instruments[ix] end h 
 members.inject({}) { |m, e| t = instruments.delete_at(0).split(','); m[e] = t.size > 1 ? t : t[0]; m } 

Se non ti preoccupi degli array di 1 elemento nel risultato, puoi usare:

 members.inject({}) { |m, e| m[e] = instruments.delete_at(0).split(','); m } 
 h = {} members.each_with_index {|item, index| h.store(item,instruments[index].split) }