# A way to initialize an array without specifying its eltype in advance?

**URL:** https://discourse.julialang.org/t/a-way-to-initialize-an-array-without-specifying-its-eltype-in-advance/47379
**Category:** General Usage
**Tags:** question
**Created:** [September 27, 2020, 11:07pm UTC](https://discourse.julialang.org/t/a-way-to-initialize-an-array-without-specifying-its-eltype-in-advance/47379 "2020-09-27T23:07:10Z")
**Posts on this page:** 13
**Page:** 1

<div class="post-metadata">

### Author: ![tomohiro\_soejima](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomohiro_soejima/32/8056_2.png) [@tomohiro\_soejima](https://discourse.julialang.org/u/tomohiro_soejima)
#### Post date: [September 27, 2020, 11:07pm UTC](https://discourse.julialang.org/t/a-way-to-initialize-an-array-without-specifying-its-eltype-in-advance/47379/1 "2020-09-27T23:07:10Z")

</div>

Hi

Often I would like to initialize an array without specifying an eltype in advance, even though I know all elements of the array will have the same concrete type. By way of example,

```julia
function makesomearray()
    arr = []
    for i in 1:10
        element = some_computation(i) #some type stable computation
        push!(arr, element)
    end
    return arr #Array{Any, 1}
end

```

where `element` can have **a fairly nontrivial type that is hard to know in advance**. Of course, the above code is not performant, since `arr` will have type `Array{Any, 1}`. In order to make it type stable, I often write something like this:

```julia
function makesomearray2()
    element = some_computation(1)
    arr = [element]
    for i in 2:10
        element = some_computation(i)
        push!(arr, element)
    end
    return arr #Array{eltype(element), 1}
end

```

which is ugly. What I much prefer of is some kind of “lazy empty array”, which does not fix its type until a first element is pushed into it, such that the following code, almost identical to `makesomearray` will return the correct type.

```julia
function makesomearray3()
    arr = LazyEmptyArray[]
    for i in 1:10
        element = some_computation(i)
        push!(arr, element) # the first invocation of this should tell the compiler what type arr should be
    end
    return arr #Array{eltype(element), 1}
end

```

My questions are

1. Is there already some macro or package for handling this kind of logic?
2. If not, is there any obstacle to implementing `LazyEmptyArray`?

Thank you!

---

<div class="post-metadata">

### Author: ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)
#### Post date: [September 27, 2020, 11:10pm UTC](https://discourse.julialang.org/t/a-way-to-initialize-an-array-without-specifying-its-eltype-in-advance/47379/2 "2020-09-27T23:10:13Z")

</div>

if you know the type (not that you have to hard-code manually):

```julia
T[]

```

If you see an input array and like to have an empty array with same elements types:

```julia
eltype(input_array)[]

```

(also checkout useful functions like `similar`)

---

<div class="post-metadata">

### Author: ![tomohiro\_soejima](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomohiro_soejima/32/8056_2.png) [@tomohiro\_soejima](https://discourse.julialang.org/u/tomohiro_soejima)
#### Post date: [September 27, 2020, 11:24pm UTC](https://discourse.julialang.org/t/a-way-to-initialize-an-array-without-specifying-its-eltype-in-advance/47379/3 "2020-09-27T23:24:47Z")

</div>

Thanks for your comment! However, those strategies do not work for the situation I have in mind. I am thinking of a scenario where there is no easy way to write down the type of `element` in advance, and the only practical way of knowing the type of `element` is via `typeof(element)`. A example might be the solution type for DifferentialEquations.jl. If you run [this tutorial code](https://diffeq.sciml.ai/stable/tutorials/ode_example/#Example-1-:-Solving-Scalar-Equations), the return type is something like

```julia
typeof(sol) = 
ODESolution{Float64,1,Array{Float64,1},Nothing,Nothing,Array{Float64,1},Array{Array{Float64,1},1},ODEProblem{Float64,Tuple{Float64,Float64},false,DiffEqBase.NullParameters,ODEFunction{false,typeof(f),LinearAlgebra.UniformScaling{Bool},Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing},Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}},DiffEqBase.StandardODEProblem},Tsit5,OrdinaryDiffEq.InterpolationData{ODEFunction{false,typeof(f),LinearAlgebra.UniformScaling{Bool},Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing},Array{Float64,1},Array{Float64,1},Array{Array{Float64,1},1},OrdinaryDiffEq.Tsit5ConstantCache{Float64,Float64}},DiffEqBase.DEStats}

```

which is practically impossible to know in advance.

---

<div class="post-metadata">

### Author: ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)
#### Post date: [September 27, 2020, 11:28pm UTC](https://discourse.julialang.org/t/a-way-to-initialize-an-array-without-specifying-its-eltype-in-advance/47379/4 "2020-09-27T23:28:36Z")

</div>

then just use `eltype` or `tyoepf`. But mind in these cases, you can probably just push to `Any[]`. I don’t see a huge complicated `Array` of `Struct` being super performant anyways. (and you’re probably not using this `array` with such needs)

---

<div class="post-metadata">

### Author: ![tomohiro\_soejima](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomohiro_soejima/32/8056_2.png) [@tomohiro\_soejima](https://discourse.julialang.org/u/tomohiro_soejima)
#### Post date: [September 27, 2020, 11:32pm UTC](https://discourse.julialang.org/t/a-way-to-initialize-an-array-without-specifying-its-eltype-in-advance/47379/5 "2020-09-27T23:32:18Z")

</div>

You have a good point that `Array` of complicated `Struct` might not be required for performance.

You suggest to use `eltype` or `typeof`. Do you mind providing a code for doing it concisely? If I trye to use `typeof(element)` to initialize an empty array, , I need to first obtain `element` somehow, and the code I write up end up looking as ugly as `makesomearray2()`.

---

<div class="post-metadata">

### Author: ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)
#### Post date: [September 27, 2020, 11:41pm UTC](https://discourse.julialang.org/t/a-way-to-initialize-an-array-without-specifying-its-eltype-in-advance/47379/6 "2020-09-27T23:41:18Z")

</div>

It all depends on how your loop works. For example, I don’t see the point of repeatedly calling `solve` and push results somewhere. Notice, if you `map(solve, array)`, the array probably will be typed

---

<div class="post-metadata">

### Author: ![benninkrs](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/benninkrs/32/3191_2.png) [@benninkrs](https://discourse.julialang.org/u/benninkrs)
#### Post date: [September 28, 2020, 12:54am UTC](https://discourse.julialang.org/t/a-way-to-initialize-an-array-without-specifying-its-eltype-in-advance/47379/7 "2020-09-28T00:54:28Z")

</div>

You could use a [comprehension](https://docs.julialang.org/en/v1/manual/arrays/#man-comprehensions). Comprehensions determine the appropriate array type as elements are added.

---

<div class="post-metadata">

### Author: ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)
#### Post date: [September 28, 2020, 1:33am UTC](https://discourse.julialang.org/t/a-way-to-initialize-an-array-without-specifying-its-eltype-in-advance/47379/8 "2020-09-28T01:33:46Z")

</div>

Or `map`: it also produces a collection with an element type that contains what actually goes in the array. For example:

```julia
julia> a = [rand(Bool) ? rand(1:10) : randstring() for _ = 1:10]
10-element Vector{Any}:
 9
  "UUa9X3To"
 6
  "5NAPmkJw"
 9
 9
 7
 1
 2
  "aCmCF7vc"

julia> map(length, a)
10-element Vector{Int64}:
 1
 8
 1
 8
 1
 1
 1
 1
 1
 8

```

---

<div class="post-metadata">

### Author: ![tomohiro\_soejima](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomohiro_soejima/32/8056_2.png) [@tomohiro\_soejima](https://discourse.julialang.org/u/tomohiro_soejima)
#### Post date: [September 28, 2020, 3:03am UTC](https://discourse.julialang.org/t/a-way-to-initialize-an-array-without-specifying-its-eltype-in-advance/47379/9 "2020-09-28T03:03:33Z")

</div>

@benninkrs @StefanKarpinski Thank you for your reply! I did not think of making a clever use of map for this purpose. That seems to work well if what I want is a single array.

Sometimes, however, I’d like to create multiple arrays from a single for loop. I am trying to figure out what is the best idiomatic way of writing that in Julia. What I can think of is something like the following:

```julia
using StructArray
using Unpack

# pattern 1 : anonymous function
USVs = map(1:L) do x
              # do something with x
              return (U=U, S=S, V=V)
end
@unpack Us, Ss, Vs = StructArray(USVs)

# pattern 2 : named function
# somefunc(i) returns a vanilla tuple (U, S, V)
Us, Ss, Vs = map(somefunc, 1:L) |> StructArray |> fieldarrays

```

While these are reasonably concise, It relies on `StructArray`. I am wondering if this is the best way to accomplish this, or if there is a more idiomatic way of doing this with Julia `Base`. Do you guys have any advice?

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [September 28, 2020, 8:03am UTC](https://discourse.julialang.org/t/a-way-to-initialize-an-array-without-specifying-its-eltype-in-advance/47379/10 "2020-09-28T08:03:49Z")

</div>

> [@tomohiro\_soejima](#):
>
> It relies on `StructArray` . I am wondering if this is the best way to accomplish this

Currently, use `StructArray`.

The same widening strategy that `collect` uses in `Base` could be ported easily to functions returning a tuple and building up a tuple of arrays, but AFAIK so far no one has bothered to do it.

---

<div class="post-metadata">

### Author: ![phg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/phg/32/17184_2.png) [@phg](https://discourse.julialang.org/u/phg)
#### Post date: [September 28, 2020, 8:54am UTC](https://discourse.julialang.org/t/a-way-to-initialize-an-array-without-specifying-its-eltype-in-advance/47379/11 "2020-09-28T08:54:19Z")

</div>

@tkf has implemented a couple of these things. There’s [`Empty`](https://github.com/JuliaFolds/BangBang.jl/blob/4e2453626e8c97c3c58aa30a24934a2415e43de9/src/NoBang/emptycontainers.jl) in BangBang.jl, which is pretty much the idea you described, and [`InitialValues.jl`](https://github.com/JuliaFolds/InitialValues.jl) for a more general idea.

---

<div class="post-metadata">

### Author: ![mschauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mschauer/32/13946_2.png) [@mschauer](https://discourse.julialang.org/u/mschauer)
#### Post date: [September 28, 2020, 9:02am UTC](https://discourse.julialang.org/t/a-way-to-initialize-an-array-without-specifying-its-eltype-in-advance/47379/12 "2020-09-28T09:02:15Z")

</div>

Some relevant discussion towards the end of [Skipping parts of a for loop in the first iteration](https://discourse.julialang.org/t/skipping-parts-of-a-for-loop-in-the-first-iteration/16252)

---

<div class="post-metadata">

### Author: ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)
#### Post date: [September 28, 2020, 9:33am UTC](https://discourse.julialang.org/t/a-way-to-initialize-an-array-without-specifying-its-eltype-in-advance/47379/13 "2020-09-28T09:33:55Z")

</div>

> [@tomohiro\_soejima](#):
>
> I’d like to create multiple arrays from a single for loop.

Here is a way to do this with Transducers.jl:

```julia
julia> using Transducers

julia> foldxl(
           ProductRF(push!!, push!!, push!!),
           ((Int(x), string(x), Symbol(x)) for x in 'a':'c'),
       )
([97, 98, 99], ["a", "b", "c"], [:a, :b, :c])

julia> typeof(ans)
Tuple{Vector{Int64}, Vector{String}, Vector{Symbol}}

```

See also [Multiple outputs usage patterns in Transducers.jl](https://juliafolds.github.io/Transducers.jl/dev/howto/useful_patterns/#Multiple-outputs)

* * *

Of course, it is totally fine to do this with normal loop:

```julia
julia> a = b = c = Union{}[]
       for x in 'a':'c'
           a = push!!(a, Int(x))
           b = push!!(b, string(x))
           c = push!!(c, Symbol(x))
       end

julia> a, b, c
([97, 98, 99], ["a", "b", "c"], [:a, :b, :c])

julia> typeof(ans)
Tuple{Vector{Int64}, Vector{String}, Vector{Symbol}}

```

However, Julia’s `for` loop sometimes does not produce efficient code for type-changing accumulators as above. This is where [FLoops.jl](https://github.com/JuliaFolds/FLoops.jl) is useful:

```julia
julia> using FLoops

julia> @floop begin
           a = b = c = Union{}[]
           for x in 'a':'c'
               a = push!!(a, Int(x))
               b = push!!(b, string(x))
               c = push!!(c, Symbol(x))
           end
       end

```
