简体   繁体   中英

Insert new key value into nested hash in Ruby

I am trying to insert a new key/value { type: 'Profile'} into the photo hash that has id = 111.

photo_hash = [{"id": "111","photo": "http://photo.com/111.jpeg"}, {"id": "222",  "photo": "http://photo.com/222.jpeg"}] 

So the final result should look like:

photo_hash = [{"id": "111","photo": "http://photo.com/111.jpeg", "type" : "Profile"}, {"id": "222",  "photo": "http://photo.com/222.jpeg"}] 

I feel like this should be pretty straight forward in Ruby but I am very stuck

The question suggests to me that the element h (a hash) of photos for which h[:id] = "111 (if there is one), is to be modified in place by adding the key-value pair :type=>"Profile" .

photos = [{"id": "111", "photo": "http://photo.com/111.jpeg"},
          {"id": "222", "photo": "http://photo.com/222.jpeg"}]

insert_item = { "type": "Profile" }

h = photos.find { |h| h[:id] == "111" }
h.update(insert_item) unless h.nil?
photos
  #=> [{:id=>"111", :photo=>"http://photo.com/111.jpeg", :type=>"Profile"},
  #    {:id=>"222", :photo=>"http://photo.com/222.jpeg"}]

See Hash#update (aka merge! ).

You need to construct a new array from your existing:

photos = [{"id": "111","photo": "http://photo.com/111.jpeg"}, {"id": "222",  "photo": "http://photo.com/222.jpeg"}]

new_photos = photos.map do |photo|
  if photo[:id] == '111'
    photo.merge(type: 'Profile')
  else
    photo
  end
end

You rly dont need to find object or create new Array . Hash it self its object and can be updated.

photos = [{"id": "111","photo": "http://photo.com/111.jpeg"}, {"id": "222",  "photo": "http://photo.com/222.jpeg"}]
photos.each do |hsh|
  if hsh[:id] == '111'
    hsh[:type] = 'Profile'
    break
  end
end
photos
# => [{:id=>"111", :photo=>"http://photo.com/111.jpeg", :type=>"Profile"}, {:id=>"222", :photo=>"http://photo.com/222.jpeg"}]

If you need to update multiple values from different objects with different ids you could also build a lookup tree. (Assuming there are no duplicate ids.)

photos = [{"id": "111","photo": "http://photo.com/111.jpeg"}, {"id": "222",  "photo": "http://photo.com/222.jpeg"}]
photo_lookup = photos.map { |photo| [photo[:id], photo] }.to_h
#=> { 
#   "111" => {"id": "111","photo": "http://photo.com/111.jpeg"},
#   "222" => {"id": "222",  "photo": "http://photo.com/222.jpeg"}
# }

Then simply fetch the photo and update the value.

photo = photo_lookup["111"] and photo.update(type: 'Profile')
#                            ^ only update photo if it is found

This solution mutates the hash, meaning the hash in photos should also be updated.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM