Reputation: 43402
I have a JSON file consisting of an array of galleries, each of which has its own array of photographs:
[
{
"title":"Some Title",
"photographs":[
{
"title": "Boat Ramp"
},
{
"title": "Security Camera"
},
{
"title": "Exhaust Vents"
},
{
"title": "Factory 1"
},
{
"title": "Factory 2"
},
{
"title": "Exhaust Vents"
},
{
"title": "Viaduct"
},
{
"title": "Girders"
},
{
"title": "Office"
}
]
}
]
I am decoding it to a hash using:
galleries = ActiveSupport::JSON.decode(File.read('db/seed/galleries.json'))
I would like to get hold of an array containing all photographs in the document.
It is possible the structure of this file may change, so I would like an answer that searches on the attribute name, not its location within the hash.
What is the simplest way of getting an array containing all photographs in all galleries that does not rely on the location of the photographs within the document?
Upvotes: 0
Views: 560
Reputation: 11494
You would need to write your own method to recursively search the decoded JSON structure for the key value. The method would need to decide how to handle an array, hash or string at each level of the json tree. Possibly something like this, which makes some assumptions about your data:
module KeyFinder
def find_by_key(object, key)
case object
when Array
object.each do |v|
result = find_by_key(v, key)
return result unless result.nil?
end
when Hash
object.each do |k, v|
if k == key
return v
else
result = find_by_key(v, key)
return result unless result.nil?
end
end
else # String
nil
end
end
end
include KeyFinder
find_by_key(galleries, "photographs")
# => [{"title"=>"Boat Ramp"}, {"title"=>"Security Camera"}, {"title"=>"Exhaust Vents"}, {"title"=>"Factory 1"}, {"title"=>"Factory 2"}, {"title"=>"Exhaust Vents"}, {"title"=>"Viaduct"}, {"title"=>"Girders"}, {"title"=>"Office"}]
Upvotes: 1