How can I transform an array of hashes response
:
response = [
{id: 1, name: 'foo', something: {}},
{id: 2, name: 'bar', something: {}}
]
where the :id
s are unique, to a hash of hashes transformed
with values as the elements of response
and the key as the corresponding :id
value turned into a string as follows?
transformed = {
'1' => {id: 1, name: 'foo', something: {}},
'2' => {id: 2, name: 'bar', something: {}}
}
Since ruby 2.4.0
you can use native Hash#transform_values
method:
response
.group_by{|h| h[:id]}
.transform_keys(&:to_s)
.transform_values(&:first)
# => {
# "1"=>{:id=>1, :name=>"foo", :something=>{}},
# "2"=>{:id=>2, :name=>"bar", :something=>{}}
# }
other options
response.map{ |i| [i[:id].to_s, i] }.to_h
#=> {"1"=>{:id=>1, :name=>"foo", :something=>{}}, "2"=>{:id=>2, :name=>"bar", :something=>{}}}
Hash[response.map{ |i| [i[:id].to_s, i] }]
#=> {"1"=>{:id=>1, :name=>"foo", :something=>{}}, "2"=>{:id=>2, :name=>"bar", :something=>{}}
response.inject({}) { |h, i| h[i[:id].to_s] = i; h }
#=> {"1"=>{:id=>1, :name=>"foo", :something=>{}}, "2"=>{:id=>2, :name=>"bar", :something=>{}}}
@Stefan's solution
response.each.with_object({}) { |i, h| h[i[:id].to_s] = i }
#=> {"1"=>{:id=>1, :name=>"foo", :something=>{}}, "2"=>{:id=>2, :name=>"bar", :something=>{}}}
@engineersmnky's solution
response.inject({}) {|h,i| h.merge({i[:id].to_s => i})}
#=> {"1"=>{:id=>1, :name=>"foo", :something=>{}}, "2"=>{:id=>2, :name=>"bar", :something=>{}}}
response = [{ id: 1, name: 'foo', something: {} },{ id: 2, name: 'bar', something: { } }]
hash = Hash.new
response.each {|a| hash[a[:id].to_s] = a }
puts hash
If you will have the id
as key in resulting hash, there is no need to keep it in the value again. See my solution using each_with_object
(with id
removed from value):
input
=> [{:id=>1, :name=>"foo", :something=>{}},
{:id=>2, :name=>"bar", :something=>{}}]
input.each_with_object({}) do |hash, out|
out[hash.delete(:id).to_s] = hash
end
=> {"1"=>{:name=>"foo", :something=>{}},
"2"=>{:name=>"bar", :something=>{}}}
Note: It will modify the input
array permanently.
However, to have the exact output as mentioned in the question, do:
input.each_with_object({}) do |hash, out|
out[hash[:id].to_s] = hash
end
=> {"1"=>{:id=>1, :name=>"foo", :something=>{}},
"2"=>{:id=>2, :name=>"bar", :something=>{}}}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.