@@ -109,6 +109,58 @@ const StructVector{T, C<:Tup, I} = StructArray{T, 1, C, I}
109109StructVector {T} (args... ; kwargs... ) where {T} = StructArray {T} (args... ; kwargs... )
110110StructVector (args... ; kwargs... ) = StructArray (args... ; kwargs... )
111111
112+ """
113+ StructArray{T}(A::AbstractArray; dims, unwrap=FT->FT!=eltype(A))
114+
115+ Construct a `StructArray` from slices of `A` along `dims`.
116+
117+ The `unwrap` keyword argument is a function that determines whether to
118+ recursively convert fields of type `FT` to `StructArray`s.
119+
120+ !!! compat "Julia 1.1"
121+ This function requires at least Julia 1.1.
122+
123+ ```julia-repl
124+ julia> X = [1.0 2.0; 3.0 4.0]
125+ 2×2 Array{Float64,2}:
126+ 1.0 2.0
127+ 3.0 4.0
128+
129+ julia> StructArray{Complex{Float64}}(X; dims=1)
130+ 2-element StructArray(view(::Array{Float64,2}, 1, :), view(::Array{Float64,2}, 2, :)) with eltype Complex{Float64}:
131+ 1.0 + 3.0im
132+ 2.0 + 4.0im
133+
134+ julia> StructArray{Complex{Float64}}(X; dims=2)
135+ 2-element StructArray(view(::Array{Float64,2}, :, 1), view(::Array{Float64,2}, :, 2)) with eltype Complex{Float64}:
136+ 1.0 + 2.0im
137+ 3.0 + 4.0im
138+ ```
139+
140+ By default, fields will be unwrapped until they match the element type of the array:
141+ ```
142+ julia> StructArray{Tuple{Float64,Complex{Float64}}}(rand(3,2); dims=1)
143+ 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}}:
144+ (0.004767505234193781, 0.27949621887414566 + 0.9039320635041561im)
145+ (0.41853472213051335, 0.5760165160827859 + 0.9782723869433818im)
146+ ```
147+ """
148+ StructArray (A:: AbstractArray ; dims, unwrap)
149+ function StructArray {T} (A:: AbstractArray ; dims, unwrap= FT-> FT!= eltype (A)) where {T}
150+ slices = Iterators. Stateful (eachslice (A; dims= dims))
151+ buildfromslices (T, unwrap, slices)
152+ end
153+ function buildfromslices (:: Type{T} , unwrap:: F , slices) where {T,F}
154+ if unwrap (T)
155+ buildfromschema (T) do FT
156+ buildfromslices (FT, unwrap, slices)
157+ end
158+ else
159+ return popfirst! (slices)
160+ end
161+ end
162+
163+
112164function Base. IndexStyle (:: Type{S} ) where {S<: StructArray }
113165 index_type (S) === Int ? IndexLinear () : IndexCartesian ()
114166end
0 commit comments