{"key_a" => "value_a", "key_b" => "value_b", "key_c" => { "key_c_a" => nil, "key_c_b" => nil, "key_c_c" => "value_c_c"}, "key_d" => nil, "key_e" => nil }
how do i map the hash such that i get the result as "key_c_a", "key_c_b", "key_d" and key_e"?
i keep getting my answer as an empty array and here is the method in the module that is used in the main class
def self.get_null_keys(container)
container.map do |key, value|
if value.is_a?(Array)
value.map { |field| render_null_fields(field) }
elsif value.is_a?(Hash)
render_null_fields(value)
elsif value.nil?
key
end
end
end
CodePudding user response:
Naive recursive way to do it:
hash = {"key_a" => "value_a", "key_b" => "value_b", "key_c" => { "key_c_a" => nil, "key_c_b" => nil, "key_c_c" => "value_c_c"}, "key_d" => nil, "key_e" => nil }
def get_null_values(hash, array = [])
hash.each do |key, value|
array << key if value.nil?
get_null_values(value, array) if value.is_a?(Hash)
end
array
end
get_null_values(hash) # ["key_c_a", "key_c_b", "key_d", "key_e"]
CodePudding user response:
Do it recursively:
h={"key_a" => "value_a", "key_b" => "value_b", "key_c" => { "key_c_a" => nil, "key_c_b" => nil, "key_c_c" => "value_c_c"}, "key_d" => nil, "key_e" => nil }
def find_nils(x, memo=[])
x.inject({}){ |m, (k, v)|
v = find_nils(v, memo) if v.is_a? Hash # arbitrarily recursive
memo << k if v.nil?
}
memo
end
Instead of inject
as a skeleton you can also use each
:
def find_nils(x, memo=[])
x.each{ |k, v|
v = find_nils(v, memo) if v.is_a? Hash # arbitrarily recursive
memo << k if v.nil?
}
memo
end
Either:
p find_nils(h)
["key_c_a", "key_c_b", "key_d", "key_e"]