In Julia, how do you create an array of unique, empty mutable objects?

Viewed 361

The helpstring for fill, says:

help?> fill
search: fill fill! finally findall filter filter! filesize filemode FileSyntax FileSchema isfile CSVFile @__FILE__ CSVFileSyntax fieldtype fieldname

  fill(x, dims)

  Create an array filled with the value x. For example, fill(1.0, (5,5)) returns a 5×5 array of floats, with each element initialized to 1.0.

...

  If x is an object reference, all elements will refer to the same object. fill(Foo(), dims) will return an array filled with the result of evaluating
  Foo() once.

Note that last paragraph:

If x is an object reference, all elements will refer to the same object. fill(Foo(), dims) will return an array filled with the result of evaluating Foo() once.

So I was wondering, how does one construct an Array of n unique objects?

E.g. say I want an array of 3 empty, separate dictionaries.


Related: Creating an Array of Arrays in Julia

3 Answers

The best I can come up with is to use a comprehension:

julia> ds = [Dict() for _ in 1:3]
2-element Array{Dict{Any,Any},1}:
 Dict()
 Dict()
 Dict()

Is this the best approach? Thanks!

Here are two alternatives I can think of:

julia> map(_ -> Dict(), 1:3)
3-element Array{Dict{Any,Any},1}:
 Dict()
 Dict()
 Dict()

julia> (_ -> Dict()).(1:3)
3-element Array{Dict{Any,Any},1}:
 Dict()
 Dict()
 Dict()

but in practice I use a comprehension as you have proposed.

As stated in the docs

fill(Foo(), dims) will return an array filled with the result of evaluating Foo() once

So this happen and that's exactly what you want to avoid:

julia> a = fill(Dict(), 4)
4-element Array{Dict{Any,Any},1}:
 Dict()
 Dict()
 Dict()
 Dict()

julia> a[1]["foo"] = :bar
:bar

julia> a
4-element Array{Dict{Any,Any},1}:
 Dict("foo" => :bar)
 Dict("foo" => :bar)
 Dict("foo" => :bar)
 Dict("foo" => :bar)

So the way to go is to use list comprehension as stated in discourse:

julia> a = [Dict() for i in 1:4]
4-element Array{Dict{Any,Any},1}:
 Dict()
 Dict()
 Dict()
 Dict()

julia> a[1]["foo"] = :bar
:bar

julia> a
4-element Array{Dict{Any,Any},1}:
 Dict("foo" => :bar)
 Dict()
 Dict()
 Dict()

Related question: https://discourse.julialang.org/t/initialize-array-of-arrays/11610/4

Related