How do i reduce the following code to one line in ruby?
unless(data["location"].nil?)
unless(data["location"]["country"].nil?)
unless(data["location"]["country"]["code"].nil?)
#some codes
end
end
end
How do i reduce the following code to one line in ruby?
unless(data["location"].nil?)
unless(data["location"]["country"].nil?)
unless(data["location"]["country"]["code"].nil?)
#some codes
end
end
end
if data["location"] && data["location"]["country"] && data["location"]["country"]["code]
Ruby's && operator is a short circut operator, so if the first operand is false, it will stop processing the rest of the condition. In addition. Any object that is not nil, is (for boolean purposes) true, so if the key exists, then it is true
You can use try method, this method supported from Rails 2.3 and has a native support from Ruby 1.9.
if data.try(:[],'location').try(:[],'country').try(:[],'code')
...
end
There is always the good old ...
if (data["location"]
and data["location"]["country"]
and data["location"]["country"]["code"])
# some code
end
You can bring out the big guns and use the andand gem. It's not a production suggestion (or even terribly serious for real life), but is fascinating and directly addresses your need.
With andand you can do
data['location'].andand['country'].andand['code']
You'll get a bonus warning about undefining object_id and how it may cause serious problems, but just smile and enjoy the metaprogramming :)
I know this is evil, but it's late for me….
class NilClass
def [](args=""); self; end
end
if data["location"]["country"]["code"]
# robot armies eat your pancakes
end
An answer
!data["location"].nil? && !data["location"]["country"].nil? && !data["location"]["country"]["code"].nil? && #some codes
But why?
Add a method to your Hash class
class Hash
def all_keys
keys = []
each_pair do |k1, v1|
if v1.is_a?(Hash)
v1.each_pair { |k2, v2|
if !v2.is_a?(Hash) then keys << [k1, k2]; next end
v2.each_pair { |k3, v3|
if !v3.is_a?(Hash) then keys << [k1, k2, k3]; next end
v3.each_pair { |k4, v4|
if !v4.is_a?(Hash) then keys << [k1, k2, k3, k4]; next end
v4.each_pair { |k5, v5|
if !v5.is_a?(Hash) then keys << [k1, k2, k3, k4, k5]; next end
v5.each_pair { |k6, v6|
if !v6.is_a?(Hash) then keys << [k1, k2, k3, k4, k5, k6]; next end
# add more v[n].each_pair ... loops to process more hash dimensions
} } } } } # "}" * 5
else
keys << [k1]
end
end
keys
end
end
Now, use this code to check if the nested key exists:
data.all_keys.first.include? "code"