Reputation: 493
I have imported a bunch of data from a .mat file (MATLAB format) and they come as dictionarys, but it's kind of anoying using them, so I wanted to pass it for a struct. I know I can do this:
using MAT
struct model
trans
means
vars
end
vars = matread("data.mat")
hmm1=model(vars["hmm1"]["trans"],vars["hmm1"]["means"],vars["hmm1"]["vars"])
Is there a way to do this without typing every key of the dictionay?
Upvotes: 4
Views: 2119
Reputation: 99
I came across the same issue: loading a Matlab file using MAT.jl which returns a nested dictionary. Instead of converting the dictionary to a (nested) struct, I wrote the following function to recursively search any (nested) path within the dictionary.
function superget(fault::Dict{String, Any}, path)
# Use 'get' recursively to find nested path in fault
if !occursin("/", path) && !occursin(".", path)
return get(fault, path, missing)
elseif occursin("/", path)
splitpath = split(path, "/")
superget(get(fault, popfirst!(splitpath), missing), join(splitpath, "/"))
elseif occursin(".", path)
splitpath = split(path, ".")
superget(get(fault, popfirst!(splitpath), missing), join(splitpath, "."))
end
end
Example usage
using MAT
vars = MAT.matread(path2file)
# defining path with '/'
range_x = superget(vars, "path/to/parameter/range_x")
# or use '.'
range_x = superget(vars, "path.to.parameter.range_x")
Upvotes: 0
Reputation: 2995
If you're only worried about the dot-access syntax à la hmm1.means
, you could instead use a NamedTuple
:
julia> vars = Dict("hmm1"=>Dict("trans"=>1, "means"=>2, "vars"=>3)) ;
julia> hmm1 = (; (Symbol(k) => v for (k,v) in vars["hmm1"])...)
(trans = 1, vars = 3, means = 2)
julia> hmm1.means
2
(Taken and adapted from Julia discourse: How to make a named tuple from a dictionary?.)
Upvotes: 1
Reputation: 7664
There's probably no way to avoid directly accessing the relevant keys of your dictionary. However, you can simplify your life a little by making a custom Model
constructor that takes in a Dict
:
using MAT
struct Model
trans
means
vars
end
function Model(d::Dict)
h = d["hmm1"]
Model(h["trans"], h["means"], h["vars"])
end
d = matread("data.mat")
Model(d)
Upvotes: 1