命名元组的Setindex

时间:2018-11-05 05:49:28

标签: julia namedtuple

我正在尝试为命名元组编写一个不变的setindex,在给定名称类型var的值类型的情况下,它将在x.var = y处创建一个新的命名元组。我现在拥有的是:

function setindex(nt::T,x,v::Val{var}) where {T,var}
  if var ∉ fieldnames(T)
    return x
  else
    typeof(x)(s == var ? y : w for (s,w) in nt)
  end
end

但是我的主要问题是,我不确定是否有一种很好的方法来迭代命名的元组以获取(name,value)对。

2 个答案:

答案 0 :(得分:7)

这是@generated版本。生成的代码非常简单并且类型稳定。

julia> @generated function setindex(x::NamedTuple,y,v::Val)
         k = first(v.parameters)
         k ∉ x.names ? :x : :( (x..., $k=y) )
       end

julia> @code_warntype setindex((a=2, b=3), 4, Val(:b))
Body::NamedTuple{(:a, :b),Tuple{Int64,Int64}}
2 1 ─ %1 = (Base.getfield)(x, :a)::Int64                                                               │╻╷╷   macro expansion
  │   %2 = %new(NamedTuple{(:a, :b),Tuple{Int64,Int64}}, %1, y)::NamedTuple{(:a, :b),Tuple{Int64,Int64}}│┃││╷  merge
  └──      return %2                                                                                   ││    

julia> @code_warntype setindex((a=2, b=3), 4, Val(:c))
Body::NamedTuple{(:a, :b),Tuple{Int64,Int64}}
2 1 ─     return x

答案 1 :(得分:1)

您可以使用pairs来为键值对提供迭代器,也可以使用类型为fieldnames的{​​{1}}并使用T或(使用{{ 1}}与命名元组变量的方式相同)。我认为您更喜欢nt[name]

keys

pairs