Two problems that are recurrent when working with these structures are finding a key in the tree and compacting (removing null or empty values) from the tree. Below there are 2 code fragments that do that.
def hash_deep_find(obj, key) if obj.respond_to?(:key?) && obj.key?(key) return obj[key] elsif obj.respond_to?(:keys) obj.keys.each do |child_key| return hash_deep_find(obj[child_key], key) end endend
def hash_deep_compact(obj) if obj.is_a?(Hash) obj = obj.delete_if { |k, v| v.blank?} obj.keys.each do |key| hash_deep_compact(obj[key]) end endend
As to not change the application structure, these methods were implemented as methods of an Utils class already present in the application. Alternatively, one could simply extend the behavior of Hash (either in the Hash class itself or a class that extends Hash) adding these 2 methods.