I have a Dict{String, <values>}
and I want to instantiate a type depending on the keys of that dict:
x = Dict("a" => 2, "b" => 0.0)
struct AnB
a::Int
b::Float64
end
y = fun(x) # returns AnB(2, 0.0)
I’m going to have groups of dicts where each group has the exact same keys. I’ll make sure that there is always a type defined with the correct fields for each group of dicts. But how do I write this fun
function so it’ll accept any of the possible dicts?
P.S.
If it helps, I’ll add that the type of the keys of the dicts doesn’t have to be String
, but instead can be Symbol
.
julia> using Parameters
julia> @with_kw struct AnB
a::Int
b::Float64
end
AnB
julia> x
Dict{String,Any} with 2 entries:
"b" => 0.0
"a" => 2
julia> AnB(; (Symbol(k) => v for (k, v) in x)...)
AnB
a: Int64 2
b: Float64 0.0
julia> x = Dict(:a => 2, :b => 0.0) # Symbols
Dict{Symbol,Any} with 2 entries:
:a => 2
:b => 0.0
julia> b = AnB(; x...)
AnB
a: Int64 2
b: Float64 0.0
3 Likes
Thanks! I started tinkering with hashing the concatenation of the keys and using Type{Val{<hash>}}
… Awesome that this is already solved.
Assuming that the type is somehow selected based on the keys, here is an example with symbols:
# define a method like below for each type
instantiate(dict::Dict{Symbol, <: Any}) =
instantiate(Val(tuple(keys(dict)...)), values(dict)...)
struct AnB
a::Int
b::Float64
end
# you can automate this step with a macro on the struct
instantiate(::Val{(:a, :b)}, a, b) = AnB(a, b)
instantiate(Dict(:a => 2, :b => 0.0)) # AnB(2, 0.0)
BTW, this problem may be a very good match for named tuples.
1 Like