# Add a property to a StructArray

**URL:** <https://discourse.julialang.org/t/add-a-property-to-a-structarray/74450>\
**Category:** General Usage\
**Tags:** question, structarrays\
**Created:** [January 12, 2022, 1:10am UTC](https://discourse.julialang.org/t/add-a-property-to-a-structarray/74450 "2022-01-12T01:10:59Z")\
**Posts on this page:** 8\
**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:** [January 12, 2022, 1:10am UTC](https://discourse.julialang.org/t/add-a-property-to-a-structarray/74450/1 "2022-01-12T01:10:59Z")

</div>

Is it possible to add a property to a StructArray?

The following code fails:

```julia
julia> using KiteUtils, StructArrays
julia> syslog=demo_syslog(7)

julia> function Base.getproperty(st::StructArray{SysState}, sym::Symbol)
           if sym == :x
               last.getfield(st, :X)
           elseif sym == :y
               last.getfield(st, :Y)
           elseif sym == :z
               last.getfield(st, :Z) # last.(st.Z)
           else
               getfield(st, sym)
           end
       end

julia> syslog.z
ERROR: type NamedTuple has no field z
Stacktrace:
 [1] component
   @ ~/.julia/packages/StructArrays/MdA9B/src/structarray.jl:307 [inlined]
 [2] getproperty(s::StructArrays.StructVector{SysState{7}, NamedTuple{(:time, :orient, :elevation, :azimuth, :l_tether, :v_reelout, :force, :depower, :v_app, :X, :Y, :Z), Tuple{Vector{Float64}, Vector{StaticArrays.MVector{4, Float32}}, Vector{Float64}, Vector{Float32}, Vector{Float32}, Vector{Float32}, Vector{Float32}, Vector{Float32}, Vector{Float32}, Vector{StaticArrays.MVector{7, Float32}}, Vector{StaticArrays.MVector{7, Float32}}, Vector{StaticArrays.MVector{7, Float32}}}}, Int64}, key::Symbol)
   @ StructArrays ~/.julia/packages/StructArrays/MdA9B/src/structarray.jl:309
 [3] top-level scope
   @ REPL[6]:1

```

Additional info:

```julia
julia> typeof(syslog)
StructVector{SysState{7}, NamedTuple{(:time, :orient, :elevation, :azimuth, :l_tether, :v_reelout, :force, :depower, :v_app, :X, :Y, :Z), Tuple{Vector{Float64}, Vector{MVector{4, Float32}}, Vector{Float64}, Vector{Float32}, Vector{Float32}, Vector{Float32}, Vector{Float32}, Vector{Float32}, Vector{Float32}, Vector{MVector{7, Float32}}, Vector{MVector{7, Float32}}, Vector{MVector{7, Float32}}}}, Int64} (alias for StructArrays.StructArray{SysState{7}, 1, NamedTuple{(:time, :orient, :elevation, :azimuth, :l_tether, :v_reelout, :force, :depower, :v_app, :X, :Y, :Z), Tuple{Array{Float64, 1}, Array{StaticArrays.MArray{Tuple{4}, Float32, 1, 4}, 1}, Array{Float64, 1}, Array{Float32, 1}, Array{Float32, 1}, Array{Float32, 1}, Array{Float32, 1}, Array{Float32, 1}, Array{Float32, 1}, Array{StaticArrays.MArray{Tuple{7}, Float32, 1, 7}, 1}, Array{StaticArrays.MArray{Tuple{7}, Float32, 1, 7}, 1}, Array{StaticArrays.MArray{Tuple{7}, Float32, 1, 7}, 1}}}, Int64})

```

Any idea?

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [June 5, 2022, 12:35pm UTC](https://discourse.julialang.org/t/add-a-property-to-a-structarray/74450/2 "2022-06-05T12:35:16Z")

</div>

Can you elaborate a bit, especially on `last` in your code?

What is it that you want as an output of `syslog.z` ?  
Same as `syslog.Z` (upperase Z!) without redefining Base.getproperty ?

And what do you mean with `last.getfield(st, :Z) # last.(st.Z)` ?  
What is the output of `last.(st.Z)` without redefining Base.getproperty ?

I tried your code but get

```julia
julia> syslog=demo_syslog(7)
ERROR: SystemError: opening file "data\\system.yaml": No such file or directory

```

---

<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:** [June 5, 2022, 1:05pm UTC](https://discourse.julialang.org/t/add-a-property-to-a-structarray/74450/3 "2022-06-05T13:05:13Z")

</div>

If you want try yourself, here a more complete explanation how to reproduce the issue:

```julia
mkdir tmp
cd tmp
julia --project="."
using Pkg
pkg"add KiteUtils"
pkg"add StructArrays"
using KiteUtils, StructArrays
copy_settings()
log = demo_syslog(7)

function Base.getproperty(st::StructArray{SysState}, sym::Symbol)
           if sym == :x
               last.getfield(st, :X)
           elseif sym == :y
               last.getfield(st, :Y)
           elseif sym == :z
               last.getfield(st, :Z) # last.(st.Z)
           else
               getfield(st, sym)
           end
       end

julia> log.z
ERROR: type NamedTuple has no field z
Stacktrace:
 [1] component
   @ ~/.julia/packages/StructArrays/rICDm/src/structarray.jl:307 [inlined]
 [2] getproperty(s::StructVector{SysState{7}, NamedTuple{(:time, :orient, :elevation, :azimuth, :l_tether, :v_reelout, :force, :depower, :steering, :heading, :course, :v_app, :vel_kite, :X, :Y, :Z), Tuple{Vector{Float64}, Vector{StaticArrays.MVector{4, Float32}}, Vector{Float64}, Vector{Float32}, Vector{Float32}, Vector{Float32}, Vector{Float32}, Vector{Float32}, Vector{Float32}, Vector{Float32}, Vector{Float32}, Vector{Float32}, Vector{StaticArrays.MVector{3, Float32}}, Vector{StaticArrays.MVector{7, Float32}}, Vector{StaticArrays.MVector{7, Float32}}, Vector{StaticArrays.MVector{7, Float32}}}}, Int64}, key::Symbol)
   @ StructArrays ~/.julia/packages/StructArrays/rICDm/src/structarray.jl:309
 [3] top-level scope
   @ REPL[17]:1

julia> log.Z
201-element Vector{StaticArrays.MVector{7, Float32}}:
 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
 [0.0, 0.0007690057, 0.0030974336, 0.007050112, 0.012737092, 0.02031671, 0.030000001]
 [0.0, 0.0015380114, 0.006194867, 0.014100224, 0.025474183, 0.04063342, 0.060000002]
 [0.0, 0.002307017, 0.009292301, 0.021150336, 0.038211275, 0.060950134, 0.09]
 [0.0, 0.0030760227, 0.012389734, 0.028200448, 0.050948367, 0.08126684, 0.120000005]
 [0.0, 0.0038450283, 0.015487167, 0.03525056, 0.06368546, 0.101583555, 0.15]
 [0.0, 0.004614034, 0.018584602, 0.04230067, 0.07642255, 0.12190027, 0.18]
 [0.0, 0.00538304, 0.021682035, 0.049350783, 0.089159645, 0.14221698, 0.21000001]
 [0.0, 0.0061520454, 0.024779469, 0.056400895, 0.10189673, 0.16253369, 0.24000001]
 [0.0, 0.006921051, 0.0278769, 0.06345101, 0.11463383, 0.18285039, 0.27]
 ⋮
 [0.0, 0.1476491, 0.59470725, 1.3536215, 2.4455216, 3.9008086, 5.76]
 [0.0, 0.1484181, 0.59780467, 1.3606716, 2.4582586, 3.9211252, 5.7900004]
 [0.0, 0.1491871, 0.6009021, 1.3677217, 2.470996, 3.941442, 5.82]
 [0.0, 0.1499561, 0.60399956, 1.3747718, 2.483733, 3.9617586, 5.8500004]
 [0.0, 0.15072511, 0.60709697, 1.3818219, 2.49647, 3.9820752, 5.8800006]
 [0.0, 0.15149412, 0.6101944, 1.388872, 2.509207, 4.002392, 5.9100003]
 [0.0, 0.15226312, 0.6132918, 1.3959222, 2.521944, 4.022709, 5.9400005]
 [0.0, 0.15303212, 0.6163893, 1.4029722, 2.5346813, 4.0430255, 5.9700003]
 [0.0, 0.15380114, 0.6194867, 1.4100224, 2.5474184, 4.063342, 6.0000005]

```

log.Z is a vector of vectors, and I want to get the last elements of each of these vectors when I type  
log.z .

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [June 5, 2022, 1:30pm UTC](https://discourse.julialang.org/t/add-a-property-to-a-structarray/74450/4 "2022-06-05T13:30:12Z")

</div>

Ok, what missed from the example before was just the

```julia
copy_settings()

```

This does what you want (only for :z):

```julia
function StructArrays.component(s::StructArray, key)
    if key == :z
		return last.(getfield(StructArrays.components(s), :Z))
	end
	getfield(StructArrays.components(s), key)
end

```

But, if this is a good idea or good style I doubt.  
E.g. what if another StructArray has some field z?

---

<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:** [June 5, 2022, 1:32pm UTC](https://discourse.julialang.org/t/add-a-property-to-a-structarray/74450/5 "2022-06-05T13:32:43Z")

</div>

This actually also works, I was not aware of this possibility:

```julia
julia> last.(log.Z)
201-element Vector{Float32}:
 0.0
 0.030000001
 0.060000002
 0.09
 0.120000005
 0.15
 0.18
 0.21000001
 0.24000001
 0.27
 ⋮
 5.76
 5.7900004
 5.82
 5.8500004
 5.8800006
 5.9100003
 5.9400005
 5.9700003
 6.0000005

```

---

<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:** [June 5, 2022, 1:33pm UTC](https://discourse.julialang.org/t/add-a-property-to-a-structarray/74450/6 "2022-06-05T13:33:45Z")

</div>

> [@oheil](#):
>
> But, if this is a good idea or good style I doubt.  
> E.g. what if another StructArray has some field z?

Is there the possibility to assign a new type name to special struct arrays?

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [June 5, 2022, 1:40pm UTC](https://discourse.julialang.org/t/add-a-property-to-a-structarray/74450/7 "2022-06-05T13:40:56Z")

</div>

Like as an alias? I don’t know of such a possibility in general.

Edited above funtion as I missed the broadcasted `last`.

---

<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:** [June 5, 2022, 2:01pm UTC](https://discourse.julialang.org/t/add-a-property-to-a-structarray/74450/8 "2022-06-05T14:01:49Z")

</div>

> Like as an alias? I don’t know of such a possibility in general.

I mean, it would be nice if StructArrays of different Structs could have different types…
