Let’s say I have a nested dictionary like :
a_nested_dict = Dict("a"=>1,"b"=>Dict("c"=>2,"d"=>[Dict("e"=>2),Dict("f"=>3)]),"g"=>[1,"h"])
How do I override individual values, using a function like:
function override_nested_dict!(nested_dict,override_elements)
for o_element in override_elements
....
end
end
Such to produce :
a_nested_dict["a"] = 10
a_nested_dict["g"][2] = "l"
a_nested_dict["b"]["d"][2] = Dict("i"=>4)
In particular I don’t know the data structure of override_elements… vector of pairs of tuples as key and values?
This one for example doesn’t work:
a_nested_dict = Dict("a"=>1,"b"=>Dict("c"=>2,"d"=>[Dict("e"=>2),Dict("f"=>3)]),"g"=>[1,"h"])
function override_nested_dict!(nested_dict,override_elements)
for o_element in override_elements
nested_dict[o_element[1]...] = o_element[2]
end
end
override_nested_dict!(a_nested_dict,["a"=>10,("g",2)=>"l",("b","d",2)=>Dict("i"=>4)])
Your override specifications are pairs of either a key and a value, or a Tuple of keys and a value. Your base case is when the first
of the pair is not a tuple, set the key/value pair in the Dict. If the first is a tuple, then extract the first element from the tuple, use it to look up an inner Dict, then recursively do the same with the remaining elements of the Tuple and the inner Dict until you have a single element left in the Tuple. Then follow the base case.
Thanks, this seems to work:
julia> function override_nested_dict!(nested_dict,override_elements)
for o_element in override_elements
td = nested_dict
o_ks = o_element[1]; o_v = o_element[2];
(typeof(o_ks) <: Tuple) || (o_ks = (o_ks,))
for (ik,k) in enumerate(o_ks)
k in keys(td) || error("Override error: Key $k not found in container $td")
ik == length(o_ks) ? (td[k] = o_v) : (td = td[k])
end
end
end
override_nested_dict! (generic function with 1 method)
julia> a_nested_dict = Dict("a"=>1,"b"=>Dict("c"=>2,"d"=>[Dict("e"=>2),Dict("f"=>3)]),"g"=>[1,"h"])
Dict{String, Any} with 3 entries:
"g" => Any[1, "h"]
"b" => Dict{String, Any}("c"=>2, "d"=>[Dict("e"=>2), Dict("f"=>3)])
"a" => 1
julia> override_elements = ["a"=>10,("g",2)=>"l",("b","d",2)=>Dict("i"=>4)]
3-element Vector{Pair{Any, Any}}:
"a" => 10
("g", 2) => "l"
("b", "d", 2) => Dict("i" => 4)
julia> override_nested_dict!(a_nested_dict,override_elements)
julia> a_nested_dict
Dict{String, Any} with 3 entries:
"g" => Any[1, "l"]
"b" => Dict
julia> override_elements2 = ["z"=>20]
1-element Vector{Pair{String, Int64}}:
"z" => 20
julia> override_nested_dict!(a_nested_dict,override_elements2)
ERROR: Override error: Key z not found in container Dict{String, Any}("g" => Any[1, "l"], "b" => Dict{String, Any}("c" => 2, "d" => [Dict("e" => 2), Dict("i" => 4)]), "a" => 10)
Stacktrace:
[1] error(s::String)
@ Base ./error.jl:35
[2] override_nested_dict!(nested_dict::Dict{String, Any}, override_elements::Vector{Pair{String, Int64}})
@ Main ./REPL[19]:7
[3] top-level scope
@ REPL[25]:1