Combine two Arrays into Hash

Ruby

Ruby Problem Overview


I've got two Arrays:

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

What I would like to do is combine these so that the resulting data structure is a Hash like so:

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

Note the value for "Matt Anderson" is now an Array instead of a string. Any Ruby wizards care to give this a shot?

I know Hash[*members.zip(instruments).flatten] combines them almost the way I want, but what about turning the "guitars, vocals" string into an array first? Thanks.

Ruby Solutions


Solution 1 - Ruby

As Rafe Kettler posted, using zip is the way to go.

Hash[members.zip(instruments)] 

Solution 2 - Ruby

Use map and split to convert the instrument strings into arrays:

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

Then use Hash[] and zip to combine members with instruments:

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

to get

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

If you don't care if the single-item lists are also arrays, you can use this simpler solution:

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

which gives you this:

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

Solution 3 - Ruby

#Example 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}

#Example 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"]}

Solution 4 - Ruby

This is the best and cleanest way to do what you want.

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

Enjoy!

Solution 5 - Ruby

h = {}
members.each_with_index do |el,ix|
	h[el] = instruments[ix].include?(",") ? instruments[ix].split(",").to_a : instruments[ix]
end
h

Solution 6 - Ruby

members.inject({}) { |m, e| t = instruments.delete_at(0).split(','); m[e] = t.size > 1 ? t : t[0]; m }

If you don't care about 1-element arrays in the result, you can use:

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

Solution 7 - Ruby

h = {}

members.each_with_index {|item, index|
     h.store(item,instruments[index].split)
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMichael IrwinView Question on Stackoverflow
Solution 1 - RubyRajView Answer on Stackoverflow
Solution 2 - RubynohatView Answer on Stackoverflow
Solution 3 - RubycoolestingView Answer on Stackoverflow
Solution 4 - RubyMario ViapianoView Answer on Stackoverflow
Solution 5 - RubyZabbaView Answer on Stackoverflow
Solution 6 - RubyDigitalRossView Answer on Stackoverflow
Solution 7 - RubymacarthyView Answer on Stackoverflow