Reputation: 443
I have an array that looks something like this
array = [{ a: 123, b: 'foo', c: 'bar' }, { a: 456, b: 'baz', c: 'qux' }]
I would like to convert this to a hash whose keys are the values of :a
in the hashes in array
, and whose values consist of hashes with :b
and :c
.
{ 123 => { b: 'foo', c: 'bar' }, 456 => { b: 'baz', c: 'qux' } }
Is this doable using ruby?
Upvotes: 0
Views: 452
Reputation: 1879
Using Hash#select method.
array.map { |v| [v.fetch(:a), v.select { |k,_| k != :a }] }.to_h
Exact :a, :b & :c
array.map { |v| [v.fetch(:a), v.select { |k,_| [:b, :c].include? k }] }.to_h
Output
{123=>{:b=>"foo", :c=>"bar"}, 456=>{:b=>"baz", :c=>"qux"}}
Upvotes: 0
Reputation: 110675
Assuming that all elements of array
(hashes) have a key :a
and that array
cannot be mutated, use Hash#reject:
array.each_with_object({}) { |g,h| h[g[:a]] = g.reject { |k,_| k == :a } }
#=> {123=>{:b=>"foo", :c=>"bar"}, 456=>{:b=>"baz", :c=>"qux"}}
Upvotes: 0
Reputation: 168101
array.each_with_object({}){|e, h| e = e.dup; h[e.delete(:a)] = e}
# => {123=>{:b=>"foo", :c=>"bar"}, 456=>{:b=>"baz", :c=>"qux"}}
If you don't care about side effects:
array.each_with_object({}){|e, h| h[e.delete(:a)] = e}
# => {123=>{:b=>"foo", :c=>"bar"}, 456=>{:b=>"baz", :c=>"qux"}}
Upvotes: 2
Reputation: 3083
I'm not sure what problem you're trying to solve. This is what I come out with:
def group_by_key(array, key)
array.map { |x| [x.delete(key), x] }.to_h
end
It works good on your example:
array = [{ a: 123, b: 'foo', c: 'bar' }, { a: 456, b: 'baz', c: 'qux' }]
group_by_key(array, :a)
#=> {123=>{:b=>"foo", :c=>"bar"}, 456=>{:b=>"baz", :c=>"qux"}}
Upvotes: 1