My goal is to determine whether there is a blank in a hash like this:
{"departure_time_slots"=>{"date"=>[""], "time"=>{"start"=>[""], "end"=>[""]}}}
The strings are nested arbitrary times. I do not want to check each of them manually. It would be nice if I can extract all the strings regardless of their depth. Is there a simple way to do that?
Here's an example of how you can extract the values. However you will still have the problem of matching the values to the keys. You can't really have both at the same time.
# Extend the Hash class
class Hash
def recursive_values
self.values.collect { |v|
v.is_a?(Hash) ? v.recursive_values : v
}.flatten
end
end
Usage:
h = {"departure_time_slots"=>{"date"=>[""], "time"=>{"start"=>[""], "end"=>[""]}}}
h.recursive_values
=> ["", "", ""]
It will be better if you will use sth like that:
departure_time_slots = {:date => Time.new, :time_start => nil, :time_end => nil}
And when you use keys in Hash it is good practise to using Symbols for keys. (http://www.ruby-doc.org/core-1.9.3/Symbol.html)
No not possible. Because they are totally present in different scope with respect to each other.
For e.g.. keys start
and end
is totally unknown and masked from the departure_time_slots
object in the example above.
One round abut way could be, getting all the values of the hashmap which are of type hashmap again and obtaining their keys recusively.
Fetch keys of departure_time_slots
and then from the value list of that map, find all the keys from every value, if that were to be a hashmap. Other than that, I don't think there is another way.
P.S. On side note, see if u can modify your structure to an array where elements can also be arrays, and try and use flatten concept of arrays. :P