Iterate over Fields of named tupel

Hi,
I have a named tupel with 3 fields with Int64-Array and 1 field with a struct called “agent”.
::NamedTuple{(:S, :I, :R, :agents),Tuple{Array{Any,1},Array{Any,1},Array{Any,1},Array{Main.workspace3.Agent,1}}}
Is there a way to iterate over the first three fields of this tuple?
Until now I just copy/pasted the code I want to run for the fields:

mean_Ss = first(simulations).S
for sim in simulations[2:end]
	mean_Ss = hcat(mean_Ss, sim.S)
end
mean_Ss = mean.(eachrow(mean_Ss))
plot!(p, 1:T, mean_Ss, label="mean S agents")

My approach was to create a for-loop like this:

for x ∈ [S, I, R]
	mean_status = getproperty(first(simulations), x)
#	or like this: first(simulations).x
	for sim in simulations[2:end]
		mean = hcat(mean, sim.x)
	end
mean = mean.(eachrow(mean))		
end

But all approaches result in an error:
MethodError: no method matching getproperty(::NamedTuple{(:S, :I, :R, :agents),Tuple{Array{Any,1},Array{Any,1},Array{Any,1},Array{Main.workspace3.Agent,1}}}, ::Main.workspace3.InfectionStatus)

For a better understanding:

mutable struct Agent
	status::InfectionStatus
	num_infected::Int64
end
@enum InfectionStatus S I R

I didn’t run this but I think the problem is here. If S I and R weren’t assigned you’d get a more helpful error. The “field names” are of type Symbol internally, so you probably want
for x ∈ [:S, :I, :R]

And at this place, you try to access a field “x” of sym, not the fieldname stored in x. Replace this with getproperty as you did above.

Edit, expanded: thing.name is just sugar for getproperty(thing, :name) and this is static (if it weren’t, you could shadow fieldnames with local variables, which would be super confusing. So if you want to compute a name, you always need the longer getproperty version. Good luck!

1 Like

Thanks! That did the magic!
With:

for x ∈ [:S, :I, :R]
    mean_status = getproperty(first(simulations), x)
    for sim in simulations[2:end]
        mean = hcat(mean, getproperty(sim, x))
    end
mean = mean.(eachrow(mean))        
end

It now runs through!

1 Like