It’s actually even more convoluted: I have a dictionary rspecs and want to allocate one of its elements, with key rname, as an array of dictionaries, whereby the array is to have length nw. This is what I tried:
roomspecs[rname]=Array{Dict{String,Any}}(undef,nw)
for j in range(1,stop=nw)
# here comes some stuff to assign a value to mat
roomspecs[rname][j]["material"]=mat
end
Although it seems that an array of dicts of the correct length is created, the attempt to assign values to its entries shown in the loop fails:
ERROR: LoadError: UndefRefError: access to undefined reference
Stacktrace:
[1] getindex(A::Vector{Dict{String, Any}}, i1::Int64)
@ Base ./array.jl:801
[2] (::var"#1#2")(f::IOStream)
@ Main ~/texts/admin/private/house/heatflow.jl:58
You are not initializing the array of Dicts. You explicitly say (undef, nw), so each position in roomspecs has a Vector that is a valid object itself but has nw positions with garbage (you did not created the Dict objects and assigned them to the vectors). You can probably do:
nw = 10
rname = 1
roomspecs = Vector{Any}(undef, 1)
roomspecs[rname]=Array{Dict{String,Any}}(undef,nw)
for j in range(1,stop=nw)
# here comes some stuff to assign a value to mat
roomspecs[rname][j] = Dict{String, Any}()
roomspecs[rname][j]["material"] = "mat"
end
The Dict{String, Any} part inside Array{...} is just specifying the type of the elements of the Array. If you create an empty Array this means you cannot push!(array, element) if element is not of the right type. But this does not create empty objects for you, even so because some types may not have an empty constructor.
roomspecs[rname]=[Dict{Symbol,Any}() for _ in 1:nw]
for j in 1:nw
# here comes some stuff to assign a value to mat
roomspecs[rname][j][:material] = mat
end
An array comprehension [Dict{...}() for _ in 1:nw] creates an array initialized with a new object in each cell
If your keys are not user-provided but can only be from a pre-defined set, using Symbols is more appropriate.