StructArrays.jl
Type
StructArrays.StructArray — TypeStructArray{T,N,C,I} <: AbstractArray{T, N}A type that stores an N-dimensional array of structures of type T as a structure of arrays.
getindexandsetindex!are overloaded to get/set values of typeT.getpropertyis overloaded to return individual field arrays.
Fields
components: aNamedTupleorTupleof the arrays used by each field. These can be accessed bycomponents(x).
Constructors
StructArrays.StructArray — MethodStructArray{T}((components...)::Union{Tuple, NamedTuple})
StructArray{T}(name1=component1, name2=component2, ...)Construct a StructArray of element type T from the specified field arrays.
StructArray((components...)::Union{Tuple, NamedTuple})
StructArray(name1=component1, name2=component2, ...)Construct a StructArray with a Tuple or NamedTuple element type from the specified field arrays.
Examples
julia> StructArray{ComplexF64}(([1.0, 2.0], [3.0, 4.0]))
2-element StructArray(::Array{Float64,1}, ::Array{Float64,1}) with eltype Complex{Float64}:
1.0 + 3.0im
2.0 + 4.0im
julia> StructArray{ComplexF64}(re=[1.0, 2.0], im=[3.0, 4.0])
2-element StructArray(::Array{Float64,1}, ::Array{Float64,1}) with eltype Complex{Float64}:
1.0 + 3.0im
2.0 + 4.0imAny AbstractArray can be used as a field array
julia> StructArray{Complex{Int64}}(([1, 2], 3:4))
2-element StructArray(::Array{Int64,1}, ::UnitRange{Int64}) with eltype Complex{Int64}:
1 + 3im
2 + 4imIf no element type T is provided, a Tuple or NamedTuple is used:
julia> StructArray((zeros(2,2), ones(2,2)))
2×2 StructArray(::Array{Float64,2}, ::Array{Float64,2}) with eltype Tuple{Float64,Float64}:
(0.0, 1.0) (0.0, 1.0)
(0.0, 1.0) (0.0, 1.0)
julia> StructArray(a=zeros(2,2), b=ones(2,2))
2×2 StructArray(::Array{Float64,2}, ::Array{Float64,2}) with eltype NamedTuple{(:a, :b),Tuple{Float64,Float64}}:
(a = 0.0, b = 1.0) (a = 0.0, b = 1.0)
(a = 0.0, b = 1.0) (a = 0.0, b = 1.0)StructArrays.StructArray — MethodStructArray{T}(A::AbstractArray; dims, unwrap=FT->FT!=eltype(A))Construct a StructArray from slices of A along dims.
The unwrap keyword argument is a function that determines whether to recursively convert fields of type FT to StructArrays.
julia> X = [1.0 2.0; 3.0 4.0]
2×2 Array{Float64,2}:
1.0 2.0
3.0 4.0
julia> StructArray{Complex{Float64}}(X; dims=1)
2-element StructArray(view(::Array{Float64,2}, 1, :), view(::Array{Float64,2}, 2, :)) with eltype Complex{Float64}:
1.0 + 3.0im
2.0 + 4.0im
julia> StructArray{Complex{Float64}}(X; dims=2)
2-element StructArray(view(::Array{Float64,2}, :, 1), view(::Array{Float64,2}, :, 2)) with eltype Complex{Float64}:
1.0 + 2.0im
3.0 + 4.0imBy default, fields will be unwrapped until they match the element type of the array:
julia> StructArray{Tuple{Float64,Complex{Float64}}}(rand(3,2); dims=1)
2-element StructArray(view(::Array{Float64,2}, 1, :), StructArray(view(::Array{Float64,2}, 2, :), view(::Array{Float64,2}, 3, :))) with eltype Tuple{Float64,Complex{Float64}}:
(0.004767505234193781, 0.27949621887414566 + 0.9039320635041561im)
(0.41853472213051335, 0.5760165160827859 + 0.9782723869433818im)StructArrays.StructArray — MethodStructArray{T}(undef, dims; unwrap=T->false)Construct an uninitialized StructArray with element type T, with Array field arrays.
The unwrap keyword argument is a function that determines whether to recursively convert arrays of element type T to StructArrays.
Examples
julia> StructArray{ComplexF64}(undef, (2,3))
2×3 StructArray(::Array{Float64,2}, ::Array{Float64,2}) with eltype Complex{Float64}:
2.3166e-314+2.38405e-314im 2.39849e-314+2.38405e-314im 2.41529e-314+2.38405e-314im
2.31596e-314+2.41529e-314im 2.31596e-314+2.41529e-314im 2.31596e-314+NaN*imStructArrays.StructArray — MethodStructArray(A; unwrap = T->false)Construct a StructArray from an existing multidimensional array or iterator A.
The unwrap keyword argument is a function that determines whether to recursively convert arrays of element type T to StructArrays.
Examples
Basic usage
julia> A = rand(ComplexF32, 2,2)
2×2 Array{Complex{Float32},2}:
0.694399+0.94999im 0.422804+0.891131im
0.101001+0.33644im 0.632468+0.811319im
julia> StructArray(A)
2×2 StructArray(::Array{Float32,2}, ::Array{Float32,2}) with eltype Complex{Float32}:
0.694399+0.94999im 0.422804+0.891131im
0.101001+0.33644im 0.632468+0.811319imFrom an iterator
julia> StructArray((1, Complex(i, j)) for i = 1:3, j = 2:4)
3×3 StructArray(::Array{Int64,2}, ::Array{Complex{Int64},2}) with eltype Tuple{Int64,Complex{Int64}}:
(1, 1+2im) (1, 1+3im) (1, 1+4im)
(1, 2+2im) (1, 2+3im) (1, 2+4im)
(1, 3+2im) (1, 3+3im) (1, 3+4im)Recursive unwrapping
julia> StructArray((1, Complex(i, j)) for i = 1:3, j = 2:4; unwrap = T -> !(T<:Real))
3×3 StructArray(::Array{Int64,2}, StructArray(::Array{Int64,2}, ::Array{Int64,2})) with eltype Tuple{Int64,Complex{Int64}}:
(1, 1+2im) (1, 1+3im) (1, 1+4im)
(1, 2+2im) (1, 2+3im) (1, 2+4im)
(1, 3+2im) (1, 3+3im) (1, 3+4im)StructArrays.collect_structarray — Functioncollect_structarray(itr; initializer = default_initializer)Collects itr into a StructArray. The user can optionally pass a initializer, that is to say a function (S, d) -> v that associates to a type and a size an array of eltype S and size d. By default initializer returns a StructArray of Array but custom array types may be used.
Accessors
StructArrays.components — Functioncomponents(s::StructArray)Return the field arrays corresponding to the various entry of the struct as a NamedTuple, or a Tuple if the struct has no names.
Examples
julia> s = StructArray(rand(ComplexF64, 4));
julia> components(s)
(re = [0.396526, 0.486036, 0.459595, 0.0323561], im = [0.147702, 0.81043, 0.00993469, 0.487091])Lazy iteration
StructArrays.LazyRow — TypeLazyRow(s::StructArray, i)A lazy representation of s[i]. LazyRow(s, i) does not materialize the ith row but returns a lazy wrapper around it on which getproperty does the correct thing. This is useful when the row has many fields only some of which are necessary. It also allows changing columns in place.
See LazyRows to get an iterator of LazyRows.
Examples
julia> t = StructArray((a = [1, 2], b = ["x", "y"]));
julia> LazyRow(t, 2).a
2
julia> LazyRow(t, 2).a = 123
123
julia> t
2-element StructArray(::Array{Int64,1}, ::Array{String,1}) with eltype NamedTuple{(:a, :b),Tuple{Int64,String}}:
(a = 1, b = "x")
(a = 123, b = "y")StructArrays.LazyRows — TypeLazyRows(s::StructArray)An iterator of LazyRows of s.
Examples
julia> map(t -> t.b ^ t.a, LazyRows(t))
2-element Array{String,1}:
"x"
"yy"Advanced APIs
StructArrays.append!! — Functiondest = StructArrays.append!!(dest, itr)Try to append itr into a vector dest, widening the element type of dest if it cannot hold the elements of itr. That is to say,
vcat(dest, StructVector(itr)) == append!!(dest, itr)holds. Note that the dest argument may or may not be the same object as the returned value.
The state of dest is unpredictable after append!! is called (e.g., it may contain some, none or all the elements from itr).
StructArrays.replace_storage — FunctionStructArrays.replace_storage(f, s::StructArray)Change storage type for components: each array v is replaced by f(v). f(v) is expected to have the same eltype and size as v.
Examples
If PooledArrays is loaded, we can pool all columns of non isbitstype:
julia> using StructArrays, PooledArrays
julia> s = StructArray(a=1:3, b = fill("string", 3));
julia> s_pooled = StructArrays.replace_storage(s) do v
isbitstype(eltype(v)) ? v : convert(PooledArray, v)
end
3-element StructArray(::UnitRange{Int64}, ::PooledVector{String, UInt32, Vector{UInt32}}) with eltype @NamedTuple{a::Int64, b::String}:
(a = 1, b = "string")
(a = 2, b = "string")
(a = 3, b = "string")Interface
StructArrays.staticschema — FunctionStructArrays.staticschema(T)The default schema for an element type T. A schema is a Tuple or NamedTuple type containing the necessary fields to construct T. By default, this will have fields with the same names and types as T.
This can be overloaded for custom types if required, in which case StructArrays.component and StructArrays.createinstance should also be defined.
julia> StructArrays.staticschema(Complex{Float64})
NamedTuple{(:re, :im),Tuple{Float64,Float64}}StructArrays.component — FunctionStructArrays.component(x, i)Default to getfield. It should be overloaded for custom types with a custom schema. See StructArrays.staticschema.
StructArrays.createinstance — FunctionStructArrays.createinstance(T, args...)Construct an instance of type T from its backing representation. args here are the elements of the Tuple or NamedTuple type specified staticschema(T).
julia> StructArrays.createinstance(Complex{Float64}, (re=1.0, im=2.0)...)
1.0 + 2.0imInternals
StructArrays.get_ith — FunctionStructArrays.get_ith(cols::Union{Tuple,NamedTuple}, I...)Form a Tuple of the Ith index of each element of cols, i.e. is equivalent to
map(c -> c[I...], Tuple(cols))StructArrays.map_params — FunctionStructArrays.map_params(f, T)Apply f to each field type of Tuple or NamedTuple type T, returning a new Tuple or NamedTuple object.
julia> StructArrays.map_params(T -> Complex{T}, Tuple{Int32,Float64})
(Complex{Int32}, Complex{Float64})StructArrays.buildfromschema — FunctionStructArrays.buildfromschema(initializer, T[, S])Construct a StructArray{T} with a function initializer, using a schema S.
initializer(T) is a function applied to each field type of S, and should return an AbstractArray{S}
S is a Tuple or NamedTuple type. The default value is staticschema(T).
StructArrays.bypass_constructor — FunctionStructArrays.bypass_constructor(T, args)Create an instance of type T from a tuple of field values args, bypassing possible internal constructors. T should be a concrete type.
StructArrays.iscompatible — FunctionStructArrays.iscompatible(::Type{S}, ::Type{V}) where {S, V<:AbstractArray}Check whether element type S can be pushed to a container of type V.
StructArrays.maybe_convert_elt — FunctionStructArrays.maybe_convert_elt(T, x)Element conversion before assignment in a StructArray. By default, this calls convert(T, x); however, you can specialize it for other types.
StructArrays.findconsistentvalue — Functionfindconsistentvalue(f, componenents::Union{Tuple, NamedTuple})Compute the unique value that f takes on each component ∈ componenents. If not all values are equal, return nothing. Otherwise, return the unique value.