Julia:跨不同结构实例的字段应用函数

Julia: applying function across fields of different struct instances

假设我有一个数组 my_array,其元素是 myType 的实例,因此数组类型由 Array{myType,1}.

给出

现在假设 my_arraymyType 的每个实例都有一些字段 x 存储数据向量(例如 typeof(instance_of_myType.x) == Array{Float32,1})。

如果我知道数组中 myType 结构的每个实例的不同字段 x 具有相同的大小,有没有一种方法可以广播一个函数(例如平均或求和)跨越数组中所有 myType 实例的不同字段 x,这将给我一个 Array{Float32,1} 向量,这是将函数应用于所有 [=15] 的结果=] my_array 中结构的字段?有没有没有 for 循环的方法,基本上就是我要问的?

这应该有效(除非您已为您的类型覆盖 getproperty):

sum.(getproperty.(my_array, :x))

这是比较广播和使用理解的完整示例:

julia> struct A{T}
              x::T
              end

julia> my_array = [A(collect(i:i+3)) for i in 1:3]
3-element Array{A{Array{Int64,1}},1}:
 A{Array{Int64,1}}([1, 2, 3, 4])
 A{Array{Int64,1}}([2, 3, 4, 5])
 A{Array{Int64,1}}([3, 4, 5, 6])

julia> sum.(getproperty.(my_array, :x))
3-element Array{Int64,1}:
 10
 14
 18

julia> [sum(v.x) for v in my_array]
3-element Array{Int64,1}:
 10
 14
 18

现在一个有趣的案例是,如果你想应用一个函数,例如sum 跨结构中字段 x 的各个元素。你可以得到这样的结果:

julia> sum(getproperty.(my_array, :x))
4-element Array{Int64,1}:
  6
  9
 12
 15

(注意这里唯一的区别是sum后面没有.

或者像这样

julia> sum(v -> v.x, my_array)
4-element Array{Int64,1}:
  6
  9
 12
 15

编辑

所以一般的方法是:

julia> tmp = getproperty.(my_array, :x)
3-element Array{Array{Int64,1},1}:
 [1, 2, 3, 4]
 [2, 3, 4, 5]
 [3, 4, 5, 6]

现在你可以写:

 [fun(getindex.(tmp, i)) for i in eachindex(tmp...)]

假设fun接受一个向量作为参数。

如果您想使用优秀的 SplitApplyCombine.jl 软件包,您可以这样写:

fun.(invert(getproperty.(my_array, :x)))

as invert 函数完全满足您的需求,例如:

  julia> invert([[1,2,3], [4,5,6]])
  3-element Array{Array{Int64,1},1}:
   [1, 4]
   [2, 5]
   [3, 6]