Array of Structs: getindex, slicing, and broadcasting getfield



I have a struct like

mutable struct State

that contains info about one object, but what I’m interested in is States, a collection of multiple State objects. I am combining each separate State into an array and defining States = Array{State}(undef, 5), for example. But now it’s difficult to broadcast States.ID. I was thinking of modifying get indices along the lines of something like

Base.getindex(states::Array{State,1}, n, ::Type{Val{:ID}}) = states[n].ID

but this doesn’t work.

What’s standard / best practice?


One solution is using


I would suggest defining an accessor function and then broadcasting that function:

id(s::State) = s.ID


Does that work for your use case?


Thanks @rdeits and @mohamed82008! I’ll try out the StructArrays package first since from a quick @btime it seems that broadcasting will allocate each call to id.(states) whereas it does it once for StructArrays


StructArrays will allocate all your ids contiguously, so if you’re accessing a lot of them at a time, it will probably be faster because it can be vectorized / take advantage of SIMD, while the array of structs cannot.
Same goes for the vals in your State.


As a follow up, can I use StructArrays in a nested way, for example:

mutable struct State
mutable struct Object
O1 = Object(State(1, :s1, 1.0), 10)
O2 = Object(State(2, :s2, 3.0), 20)
O3 = Object(State(3, :s2, 3.0), 30)
Os = StructArray([O1; O2; O3])

so that I can access

I can’t assign StructArray( to, but I can access as StructArray( However, this feels awkward.

EDIT: it looks like it’s possible to define Cell from here


IIUC, you want to access the fields in a view. Use MappedArrays:

using MappedArrays
Os_st = mappedarray((x) ->, Os)


Alternatively, Os = StructArray(objects; unwrap = t -> t <: State) works for objects = [O1; O2; O3]!