使用`Base.@kwdef`广播结构的创建

4
如果我有一个要创建结构体数组的大型结构体(例如,稍后创建 StructArray ),那么当我拥有关键字默认值时,如何创建结构体数组。
例如:
Base.@kwdef struct MyType
  a = 0
  b = 0
  c = 0
  d = 0
  ... # can be up to 10 or 20 fields
end
Base.@kwdef很好用,因为我可以使用MyType(b=10,e=5)创建对象,但有时我有参数数组。我想能够广播或简洁地构建结构体的数组。
也就是说,我想以下代码将创建三个MyType的数组:MyType.(c=[5,6,7],d = [1,2,3]) 但实际上它只创建了一个MyType,其中cd是数组而不是标量值。
有哪些方法可以保持Base.@kwdef的便利性和易于构造结构体的数组?
2个回答

5

这似乎是一个很好的生成式用例:

julia> [MyType(c=cval, d=dval) for (cval, dval) in zip([5, 6, 7], [1, 2, 3])]
3-element Vector{MyType}:
 MyType(0, 0, 5, 1)
 MyType(0, 0, 6, 2)
 MyType(0, 0, 7, 3)

另一种可能性(基于这个答案)是显式地自行执行广播调用:

julia> broadcast((cval, dval) -> MyType(c = cval, d = dval), [5, 6, 7], [1, 2, 3])
3-element Vector{MyType}:
 MyType(0, 0, 5, 1)
 MyType(0, 0, 6, 2)
 MyType(0, 0, 7, 3)

或者等价于在评论中提到的这样写:((cval, dval) -> MyType(c = cval, d = dval)).([5, 6, 7], [1, 2, 3])

在这些方法中,我认为数组推导式是最清晰和最明显的方法。


2

根据这篇文章:https://github.com/JuliaLang/julia/issues/34737,目前没有适合你的情况的内置语法。

一种选择是使用推导式(见另一个答案),第二种选择(我更喜欢这个)是构建一个匿名函数并对其进行向量化,例如:

julia> ((x,y)->MyType(;c=x,d=y)).([1,2],[3,5])
2-element Vector{MyType}:
 MyType(0, 0, 1, 3)
 MyType(0, 0, 2, 5)

也可以直接调用广播:

julia> broadcast((x,y)->MyType(;c=x,d=y), [1,2],[3,5])
2-element Vector{MyType}:
 MyType(0, 0, 1, 3)
 MyType(0, 0, 2, 5)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接