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"