I have written this function. The problem is that args... will produce a Tuple. When called recursively, i will have a Tuple of Tuples and I don’t know how to flatten it or to avoid this. I can fix it by making args::Tuple and calling like this: dig(nested, (:a, :b)), but I find this somewhat uglier.
function dig(dict::Dict, args...)
if haskey(dict, args[1])
aux = dict[args[1]]
if length(args[2:end]) > 0
dig(access, args[2:end])
else
aux
end
end
end
How can I “splat” args when maing the recursive call or flatten the Tuple?
dig(dict::AbstractDict, key, keys...) = dig(dict[key], keys...)
dig(x) = x
This throws KeyError rather than returning nothing on missing key, but should be easy to modify if you really want to return nothing as in your example.
EDIT: alternately
@DNF I didn’t find foldl to be much faster, at least after doing the necessary modifications so it doesn’t fail when the key isn’t found. And @yha first approach I’d say is conceptually simpler. Your solution is closer, although it would fail when passed :a, :b, :c if :bdoesn’t exist already.
This is just what I was looking for. One nice thing about Ruby’s dig is it can be used to access nested arrays as well as dicts. This is handy for working with responses from Elasticsearch. So I would expand @Amval’s answer to: