如何在 Julia 中从字典创建结构体或类型?

问题描述 投票:0回答:3

我从 .mat 文件(MATLAB 格式)导入了一堆数据,它们以字典的形式出现,但使用它们有点烦人,所以我想将其传递为结构体。我知道我能做到:

using MAT

struct model
    trans
    means
    vars
end

vars = matread("data.mat")
hmm1=model(vars["hmm1"]["trans"],vars["hmm1"]["means"],vars["hmm1"]["vars"])

有没有办法不用输入字典的每个键就能做到这一点?

matlab dictionary struct julia
3个回答
1
投票

可能无法避免直接访问字典的相关键。但是,您可以通过创建一个接受

Model
的自定义
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)

1
投票

如果您只担心点访问语法 à la

hmm1.means
,您可以使用
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

(取自并改编自 Julia 话语:如何从字典中创建命名元组?。)


0
投票

我遇到了同样的问题:使用 MAT.jl 加载 Matlab 文件,该文件返回嵌套字典。我没有将字典转换为(嵌套)结构,而是编写了以下函数来递归搜索字典中的任何(嵌套)路径。

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

使用示例

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")
© www.soinside.com 2019 - 2024. All rights reserved.