# Access StaticArray fields in a StructArray

**URL:** <https://discourse.julialang.org/t/access-staticarray-fields-in-a-structarray/110249>\
**Category:** General Usage\
**Tags:** staticarrays, structarrays\
**Created:** [February 15, 2024, 1:16pm UTC](https://discourse.julialang.org/t/access-staticarray-fields-in-a-structarray/110249 "2024-02-15T13:16:53Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![sijo](https://avatars.discourse-cdn.com/v4/letter/s/da6949/32.png) [@sijo](https://discourse.julialang.org/u/sijo)\
**Post date:** [February 15, 2024, 1:16pm UTC](https://discourse.julialang.org/t/access-staticarray-fields-in-a-structarray/110249/1 "2024-02-15T13:16:53Z")

</div>

StaticArrays defines properties `x`, `y`, `z` on `SVector{3}`:

```julia
using StaticArrays

v = SA[1,2,3]
v.x # returns 1

```

However these accessors don’t work on StructArrays:

```julia
using StructArrays

A = StructArray([v, 2v])
A.x # gives ERROR: type Tuple has no field x

```

I thought this was because `propertynames(v)` returns `(:data,)` so I defined

```julia
Base.propertynames(x::SVector{3}) = (:x, :y, :z)

```

but I still get the same error with `A.x`. How can I get this to work, and can we get this to work by default?

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [February 15, 2024, 2:23pm UTC](https://discourse.julialang.org/t/access-staticarray-fields-in-a-structarray/110249/2 "2024-02-15T14:23:44Z")

</div>

It requires special handling, by default StructArrays accesses fields and not properties. See my PR to add this feature – [support named properties in StructArray{SVector} by aplavin · Pull Request #277 · JuliaArrays/StructArrays.jl · GitHub](https://github.com/JuliaArrays/StructArrays.jl/pull/277). Created last June, and unfortunately got no response from StructArrays devs at all.

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [February 15, 2024, 2:39pm UTC](https://discourse.julialang.org/t/access-staticarray-fields-in-a-structarray/110249/3 "2024-02-15T14:39:36Z")

</div>

If you are willing to define methods on types you do not own, you could just define `Base.getproperty` for `Vector{<: SVector}`.

```julia-repl
julia> function Base.getproperty(v::Vector{<: SVector{3}}, s::Symbol)
           hasproperty(first(v), s) ?
               getproperty.(v, s) :
               getproperty(v, s)
       end

julia> A = [v, 2v]
2-element Vector{SVector{3, Int64}}:
 [1, 2, 3]
 [2, 4, 6]

julia> A.x
2-element Vector{Int64}:
 1
 2

julia> A.y
2-element Vector{Int64}:
 2
 4

julia> A.z
2-element Vector{Int64}:
 3
 6

```

---

<div class="post-metadata">

**Author:** ![sijo](https://avatars.discourse-cdn.com/v4/letter/s/da6949/32.png) [@sijo](https://discourse.julialang.org/u/sijo)\
**Post date:** [February 15, 2024, 3:14pm UTC](https://discourse.julialang.org/t/access-staticarray-fields-in-a-structarray/110249/4 "2024-02-15T15:14:00Z")

</div>

Thanks but I’m trying to understand how to make it work with StructArrays…

@aplavin I wonder why it doesn’t use properties… But even with fields, the following should work no?

```julia
Base.fieldnames(::Type{<:SVector{3}}) = (:x, :y, :z)

v = SA[1,2,3]
fieldnames(typeof(v) # returns (:x, :y, :z) as expected

```

but I still get the same error.

It would be great to have your PR merged but I wonder if there’s not a larger fix to make here. It seems to me that this should “just work” using properties (or maybe fields) for any type that is unwrapped by StructArray.

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [February 15, 2024, 9:31pm UTC](https://discourse.julialang.org/t/access-staticarray-fields-in-a-structarray/110249/5 "2024-02-15T21:31:38Z")

</div>

> [@mkitti](#):
>
> you could just define `Base.getproperty` for `Vector{<: SVector}`

A major point of StructArrays is efficiency – there, accessing a column like `arr.x` is free. This is difficult to achieve with `arr::Vector`.  
But should be possible with stuff like `view` and `reinterpret`, would be a nice excercise btw!

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [February 15, 2024, 9:34pm UTC](https://discourse.julialang.org/t/access-staticarray-fields-in-a-structarray/110249/6 "2024-02-15T21:34:27Z")

</div>

> [@sijo](#):
>
> I wonder why it doesn’t use properties…

It’s impossible (?) to do generically. How would a StructArray look like, if its elements have computed properties? Even for `StructArray{SVector}` – there are both `data` and `x, y, z` properties that refer to the same data.

Currently, StructArray stores each field of its content separately: all `a` fields go to one array, all `b` fields go to another, etc. With fields, it’s unambiguous.

> [@sijo](#):
>
> `Base.fieldnames(::Type{<:SVector{3}}) = (:x, :y, :z)`

Whew, I can imagine this definition breaking some fundamental assumptions in Julia… (:  
Changing `fieldnames` this way doesn’t change the fact that the only actual field of an `SVector` is `data`.

---

<div class="post-metadata">

**Author:** ![sijo](https://avatars.discourse-cdn.com/v4/letter/s/da6949/32.png) [@sijo](https://discourse.julialang.org/u/sijo)\
**Post date:** [February 16, 2024, 8:35am UTC](https://discourse.julialang.org/t/access-staticarray-fields-in-a-structarray/110249/7 "2024-02-16T08:35:05Z")

</div>

That was just a test to try and understand how StructArrays works, I’m not saying that StaticArrays should overload `fieldnames` :). But I do wonder why the overload makes no difference… maybe because static arrays are special cased?

> [@aplavin](#):
>
> It’s impossible (?) to do generically. How would a StructArray look like, if its elements have computed properties? Even for `StructArray{SVector}` – there are both `data` and `x, y, z` properties that refer to the same data.

I see that now. We don’t want the redundancy of storing the properties in addition to the fields, and we cannot in general reconstruct the fields from the properties.
