arrays - How to deep search into hash in Ruby -
i have key contain hash , array , want search value result web app.
for example: search_key = {search: [{user: [:first_name, {address: [:state, :city, :zip]}]}, :count], search2: [:location]}
search_key can contain key , value. here key not static creating dynamic may any.
db_data = { search{ user: { first_name: "test user", address: { street: "main street", state: nil, city: "delhi", zip: "12345" }, }, count: 55 test: 123 }, search2:{ location: "main_data" mobile_no: '9998887776' } }
i need fetch check info nowadays or not below key basis:
search_key = {search: [{user: [:first_name, {address: [:state, :city, :zip]}]}, :count], search2: [:location]}
here search_key means:
db_data[:search] db_data[:search][:user] db_data[:search][:user][:first_name] db_data[:search][:user][:address] db_data[:search][:user][:address][:state] db_data[:search][:user][:address][:city] db_data[:search][:user][:address][:zip] db_data[:search][:count] db_data[:search2] db_data[:search2][:location]
**note:: search_key not static. search_key's key alter , search_key may type, hash of array, array of hash. array of array, hash of hash of hash
i need check key nowadays or not if 1 of key nil should homecoming false
in db_data db_data[:search][:user][:address][:state] nil function should homecoming false.
if value exist in db_data[:search][:user][:address][:state] function should homecoming true.
[edit]:
i have tried function
def data_present?(data, keys) keys.each |k,v| homecoming false if data[k].nil? if v.is_a? array v.each |a| if a.is_a? hash data_present?(data[k], a) if data[k].is_a?hash homecoming data[k].each{|r| homecoming data_present?(r, v) } if data[k].is_a?array else homecoming false if data[k][a].nil? end end end end end
called
data_present?(db_data, search_key)
the recursive function phone call not working properly. please allow me know doing wrong
are looking this?
class hash def flatten_to_key_hierarchy(exclude_nils=false) deep_key_retrieval(exclude_nils).each_with_object({}) |h,obj| obj.merge!(h) end end def deep_key_retrieval(exclude_nils=false) map |k,v| if v.is_a?(hash) hash[k,v.deep_key_retrieval] else k unless v.nil? && exclude_nils end end.compact end end
this produce
db_data = { :search=>{ :user=>{ :first_name=>"test user", :address=>{ :street=>"main street", :state=>nil, :city=>"delhi", :zip=>"12345"} }, :count=>55, :test=>123 }, :search2=>{ :location=>"main_data", :mobile_no=>"9998887776" } } db_data.flatten_to_key_hierarchy #=>{:search=>[{:user=>[:first_name, {:address=>[:street, :state, :city, :zip]}]}, :count, :test], :search2=>[:location, :mobile_no]}
like said not sure understand looking seems match intended result.
saw updated question. seek adding above
def data_present?(input={},valid_object={},exclude_nils=false) input = input.flatten_to_key_hierarchy(exclude_nils) validate_against_keys(input,valid_object) end private def validate_against_keys(input={},valid_object={}) valid_object.each |k,v| homecoming false unless input.has_key?(k) && input[k].class == v.class if v.is_a?(hash) validate_against_keys(input[k],v) elsif v.is_a?(array) homecoming false unless v - input[k] == [] end end true end
#data_present?
take raw db_data
input , determined construction valid_object. ignore additional keys in db_data looking ones specified in test_data
test_data = db_data.flatten_to_key_hierarchy data_present?(db_data,test_data,true) #=> true test_data[:search].delete(:test) data_present?(db_data,test_data,true) #=> true test_data[:search] << :something_else data_present?(db_data,test_data,true) #=> false
ruby arrays hash
No comments:
Post a Comment