# Converting a vector of structs to a struct of vectors

**URL:** <https://discourse.julialang.org/t/converting-a-vector-of-structs-to-a-struct-of-vectors/54800>\
**Category:** General Usage\
**Tags:** question\
**Created:** [February 7, 2021, 3:53pm UTC](https://discourse.julialang.org/t/converting-a-vector-of-structs-to-a-struct-of-vectors/54800 "2021-02-07T15:53:15Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [February 7, 2021, 3:53pm UTC](https://discourse.julialang.org/t/converting-a-vector-of-structs-to-a-struct-of-vectors/54800/1 "2021-02-07T15:53:15Z")

</div>

Hello,

I have the following struct:

```julia
using Rotations, StaticArrays

const MyFloat = Float32
const SEGMENTS = 7 # number of tether segments

struct SysState
    time::Float64 # time since launch in seconds
    orient::Quat # orientation of the kite
    X::MVector{SEGMENTS+1, MyFloat} # vector of particle positions in x
    Y::MVector{SEGMENTS+1, MyFloat} # vector of particle positions in y
    Z::MVector{SEGMENTS+1, MyFloat} # vector of particle positions in z
end 

```

Then I create an array of these structs:

```julia
# create a demo state with a given height and time
function demo_state(height=6.0, time=0.0)
    a = 10
    X = range(0, stop=10, length=SEGMENTS+1)
    Y = zeros(length(X))
    Z = (a .* cosh.(X./a) .- a) * height/ 5.430806 
    orient = UnitQuaternion(1.0,0,0,0)
    return SysState(time, orient, X, Y, Z)
end

# create a demo flight log with given name [String] and duration [s]
const SAMPLE_FREQ=20
function demo_log(name="Test flight", duration=10)
    delta_t = 1.0 / SAMPLE_FREQ
    t_max = 10.0
    max_height = 6.0
    steps = Int(t_max * SAMPLE_FREQ) + 1
    log = Vector{SysState}(undef, steps)
    for i in range(0, length=steps)
        log[i+1] = demo_state(max_height * i/steps, i*delta_t)
    end
    return log
end

```

Finally I want to create a struct of vectors (sov) out of this vector of structs (vos) to be able to access the elements easily, like that:

```julia
vos = demo_log()
sov = vos2sov(vos) # how can I implement this function?
println(sov.time) # should print a vector of Float64
println(sov.orient) # should print a vector of quaternions

```

How can I implement the function vos2sov?

I looked at the package StructArrays.jl, but it seams as if it cannot handle structs that are composed of different types.

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [February 7, 2021, 4:51pm UTC](https://discourse.julialang.org/t/converting-a-vector-of-structs-to-a-struct-of-vectors/54800/2 "2021-02-07T16:51:27Z")

</div>

I was wrong, StructArrays CAN handle structs that are composed of different types. Example:

```julia
using StructArrays

struct Compound
    time::Float64
    name::String
end

sa = StructArray{Compound}(([1.0, 2.0], ["Hund", "Hase"]))

println(sa.time)
println(sa.name)

```

I still have to figure out how to implement the function vos2sov in a generic way. I don’t want to change this function when the struct changes.

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [February 7, 2021, 5:14pm UTC](https://discourse.julialang.org/t/converting-a-vector-of-structs-to-a-struct-of-vectors/54800/3 "2021-02-07T17:14:45Z")

</div>

Ok, this function partially works:

```julia
function vos2sov(log::Vector)
    steps=length(log)
    time_vec = Vector{Float64}(undef, steps)
    orient_vec = Vector{Quat}(undef, steps)
    X_vec = Vector{MVector{SEGMENTS+1, MyFloat}}(undef, steps)
    Y_vec = Vector{MVector{SEGMENTS+1, MyFloat}}(undef, steps)
    Z_vec = Vector{MVector{SEGMENTS+1, MyFloat}}(undef, steps)
    for i in range(1, length=steps)
        state=log[i]
        time_vec[i] = state.time
        orient_vec[i] = state.orient
        X_vec[i] = state.X
        Y_vec[i] = state.Y
        Z_vec[i] = state.Z
    end
    return StructArray{SysState}((time_vec, orient_vec, X_vec, Y_vec, Z_vec))
end

```

How can I rewrite it such that it works with any struct in a generic way?

---

<div class="post-metadata">

**Author:** ![vavrines](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vavrines/32/8024_2.png) [@vavrines](https://discourse.julialang.org/u/vavrines)\
**Post date:** [February 8, 2021, 8:09pm UTC](https://discourse.julialang.org/t/converting-a-vector-of-structs-to-a-struct-of-vectors/54800/4 "2021-02-08T20:09:13Z")

</div>

Maybe you could try working with list comprehension.

```julia
julia> struct Foo
         a
       end

julia> foo = Foo(1.0)
Foo(1.0)

julia> fa = [foo, foo]
2-element Vector{Foo}:
 Foo(1.0)
 Foo(1.0)

julia> a = [x.a for x in fa]
2-element Vector{Float64}:
 1.0
 1.0

julia> struct Sol
         a
       end

julia> sol = Sol(a)
Sol([1.0, 1.0])

```
