Reputation: 734
I have this value
{:cat=>["cat1", "cat2", "cat3"], :dog=>["dog1", "dog2", "dog3"]}
And I'm looking to retrieve/shift values from each key:
ie:
get the following:
[{:cat => "cat1", :dog => "dog1"}, {:cat => "cat2", :dog => "dog2"} ... etc]
I'm really not sure the best way to approach this, any suggestions?
Edit:
So far I have:
a[a.keys.first].dup.map{|c| a.map{|index, vals| vals.shift}}
# => [["cat1", "dog1"], ["cat2", "dog2"], ["cat3", "dog3"]]
Though not quite what I want due to lack of keys.
Upvotes: 1
Views: 698
Reputation: 168121
h = {:cat=>["cat1", "cat2", "cat3"], :dog=>["dog1", "dog2", "dog3"]}
ks = h.keys
h.values.transpose.map{|vs| Hash[[ks, vs].transpose]}
# => [
# {:cat => "cat1", :dog => "dog1"},
# {:cat => "cat2", :dog => "dog2"},
# {:cat => "cat3", :dog => "dog3"}
# ]
Or, strongly pushing a one-liner, slightly sacrificing the speed:
h.values.transpose.map{|vs| Hash[[h.keys, vs].transpose]}
Upvotes: 1
Reputation: 34186
Doesn't modify original hash:
h = {:cat=>["cat1", "cat2", "cat3"], :dog=>["dog1", "dog2", "dog3"]}
h.values.first.zip(h.values.last).map do |value_pair|
Hash[ h.keys.zip(value_pair) ]
end
# => [{:cat=>"cat1", :dog=>"dog1"}, {:cat=>"cat2", :dog=>"dog2"}, {:cat=>"cat3", :dog=>"dog3"}]
h
# => {:cat=>["cat1", "cat2", "cat3"], :dog=>["dog1", "dog2", "dog3"]}
Array#zip: http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-zip
Upvotes: 1
Reputation: 3742
cats_and_dogs = {:cat=>["cat1", "cat2", "cat3"], :dog=>["dog1", "dog2", "dog3"]}
cats_with_dogs = []
i = 0
cats_and_dogs[:cat].each do |e|
cats_with_dogs << {cat: cats_and_dogs[:cat][i], dog: cats_and_dogs[:dog][i]}
i+=1
end
cats_with_dogs # [{:cat=>"cat1", :dog=>"dog1"}, {:cat=>"cat2", :dog=>"dog2"}, {:cat=>"cat3", :dog=>"dog3"}]
Upvotes: 0
Reputation: 230366
What about this?
a = {:cat=>["cat1", "cat2", "cat3"], :dog=>["dog1", "dog2", "dog3"]}
a1 = a.each_with_object({}) do |(k, vals), memo|
shifted = vals.shift
memo[k] = shifted
end
a # => {:cat=>["cat2", "cat3"], :dog=>["dog2", "dog3"]}
a1 # => {:cat=>"cat1", :dog=>"dog1"}
Upvotes: 3