如何操作命名元组

ffe*_*tte 5 julia

我喜欢NamedTuple 很多的想法 ,作为两者之间的中间地带Tuple和完整的、用户定义的复合类型。

我知道如何构建命名元组并访问其字段之一

julia> nt = (a=1, b=2.0)
(a = 1, b = 2.0)

julia> nt.a
1
Run Code Online (Sandbox Code Playgroud)

然而,我知道的不多,甚至不知道是否有可能做更多的事情。我想了很多我们可以操作普通元组的方法(通常涉及splatting),并想知道其中一些是否也适用于命名元组。例如,如何:

  • NamedTuple从字段和值列表动态构建
  • 成长一个 NamedTuple,即向其添加新的字段值对
  • “更新”(在不可变的意义上)现有命名元组中的字段

ffe*_*tte 10

NamedTupleTools 软件包包含许多旨在使使用NamedTuples更直接的工具。但是这里有一些可以“手动”对它们执行的基本操作:


创建

       # regular syntax
julia> nt = (a=1, b=2.)
(a = 1, b = 2.0)

       # empty named tuple (useful as a seed that will later grow)
julia> NamedTuple()
NamedTuple()

       # only one entry => don't forget the comma
julia> (a=1,)
(a = 1,)
Run Code Online (Sandbox Code Playgroud)


成长与“改造”

这是可能的 merge两个命名元组创建一个新的:

julia> merge(nt, (c=3, d=4.))
(a = 1, b = 2.0, c = 3, d = 4.0)
Run Code Online (Sandbox Code Playgroud)

...或者NamedTuple通过在创建一个新的时将它泼洒来重新使用现有的:

julia> (; nt..., c=3, d=4.)
(a = 1, b = 2.0, c = 3, d = 4.0)
Run Code Online (Sandbox Code Playgroud)

当多次出现相同的字段名称时,会保留最后一次出现的名称。这允许一种“带修改的复制”形式:

julia> nt
(a = 1, b = 2.0)

julia> merge(nt, (b=3,))
(a = 1, b = 3)

julia> (; nt..., b=3)
(a = 1, b = 3)
Run Code Online (Sandbox Code Playgroud)


动态操作

field=>value在上面介绍的各种技术中使用对允许更动态的操作:

julia> field = :c;

julia> merge(nt, [field=>1])
(a = 1, b = 2.0, c = 1)

julia> (; nt..., field=>1)
(a = 1, b = 2.0, c = 1)
Run Code Online (Sandbox Code Playgroud)

可以使用相同的技术NamedTuples从现有的动态数据结构进行构建

julia> dic = Dict(:a=>1, :b=>2);
julia> (; dic...)
(a = 1, b = 2)

julia> arr = [:a=>1, :b=>2];
julia> (; arr...)
(a = 1, b = 2)
Run Code Online (Sandbox Code Playgroud)


迭代

迭代 aNamedTuple迭代它的值:

julia> for val in nt
           println(val)
       end
1
2.0
Run Code Online (Sandbox Code Playgroud)

与所有键->值结构一样,该 keys函数可用于迭代字段:

julia> for field in keys(nt)
           val = nt[field]
           println("$field => $val")
       end
a => 1
b => 2.0
Run Code Online (Sandbox Code Playgroud)