Generically create an instance of `AA <: AbstractArray` with contents 1,2,3

This is a fairly concrete question: the user passes in a type AA <: AbstractArray and I want to make a concrete instantiation of this type which contains some specified data, e.g. [1,2,3]. Here is the best I’ve come up with using the interface specified here: Interfaces · The Julia Language

arr = similar(AA, 3)
arr .= 1:3

However, this will not work if e.g. arr is mutable (whereas in theory this makes sense for immutable arrays too).

Some special cases of this problem of instantiating an array type with concrete data are covered by e.g. the zeros and ones functions (although they are only defined in Base for Array so I’m not sure if I can even assume their existence…), but is there a general way of solving this?

How about converting an existing array to the desired type? Perhaps:

using StaticArrays: SVector

convert(AA, SVector(1, 2, 3))

or just call the constructor:

AA(SVector(1, 2, 3))

Not sure how general this is, but one option is:

using Setfield
function newarr(A::T) where T
    arr = similar(A, 3)
    for i in 1:3
       @set! arr[i] = i
    end
    return T(arr)
end

It works for some very different types:

julia> using SparseArrays, StaticArrays

julia> A = sparsevec([1,5,10], rand(3))
10-element SparseVector{Float64, Int64} with 3 stored entries:
  [1 ]  =  0.269524
  [5 ]  =  0.715611
  [10]  =  0.629861

julia> newarr(A)
3-element SparseVector{Float64, Int64} with 3 stored entries:
  [1]  =  1.0
  [2]  =  2.0
  [3]  =  3.0

julia> A = rand(SVector{3,Float64})
3-element SVector{3, Float64} with indices SOneTo(3):
 0.7228423544347192
 0.771679776967447
 0.13509032343576854

julia> newarr(A)
3-element SVector{3, Float64} with indices SOneTo(3):
 1.0
 2.0
 3.0

(for the static arrays only if the input has length 3, but I’m not sure if there is any other interpretation for that in this case)

For many array types, this only makes limited sense. For example, if AA in your example is an OffsetArray, or a KeyedArray, then you don’t have any information on the offset or axis keys.

So, the question is what kind of array types do you have in mind? If they implement similar(T, ...), then your original solution would work and always return a mutable array (not always of the specified type, eg for static arrays).

2 Likes