3

i would like to populate an array of arrays with integers in julia. the following works:

a = Array{Int64}[]
push!(a, [1,2,3])

but this doesn't:

a = Array{Array{Int64}}[]
push!(a, [1, 2, 3])

the error is: MethodError: Cannot `convert` an object of type Int64 to an object of type Array{Int64,N} where N

can someone explain why? it seems like Array{Array{Int64}} should be the type of array whose elements are arrays containing Int64 values whereas Array{Int64} is an array of integers. yet a = Array{Int64}[] seems to initialize an array of arrays containing integers and not an array of integers? can someone clarify the logic here?

4
  • I believe you want append not push. Commented Jul 29, 2019 at 20:19
  • 1
    The simple explanation is that T[] creates an empty Vector{T}. So Array{Int}[] creates a Vector{Array{T}}. Be aware that you should not use Array{T}. Always use Vector{T} instead, or alternatively specify the number of dimensions, as in Array{Int, 1}. My advice: always use Vector{T} and Matrix{T} instead of Array{T, 1} and Array{T, 2}. Never use Array{T}, it creates an abstract type. Commented Jul 29, 2019 at 21:17
  • @DNF what do you mean abstract type for array? the docs say Julia provides the Vector and Matrix constructor functions, but these are simply aliases for uninitialized one and two dimensional arrays - isn't Vector an alias for Array? The default type for [1,2,3] is array. Commented Jul 29, 2019 at 21:24
  • Yes, Vector{T} is an alias for Array{T, 1} and Matrix{T} is an alias for Array{T,2}. The problem is that people always forget to specify the dimensionality, writing Array{T} instead. This is an abstract type, because it's a union of all arrays of all dimensionalities with the element type T. Writing Vector or Matrix ensures that you do not forget the dimensionality, and it makes your code more readable. Commented Jul 29, 2019 at 21:38

1 Answer 1

3

In

a = Array{Int64}[]
push!(a, [1,2,3])

is a vector of arrays and after the operation you have a 1-element vector containing one array:

julia> a
1-element Array{Array{Int64,N} where N,1}:
 [1, 2, 3]

julia> a[1]
3-element Array{Int64,1}:
 1
 2
 3

While:

a = Array{Array{Int64}}[]

creates you a vector of arrays of arrays:

julia> a = Array{Array{Int64}}[]
0-element Array{Array{Array{Int64,N} where N,N} where N,1}

so you can push! into it arrays of arrays, e.g.:

julia>     push!(a, [[1,2,3]])
1-element Array{Array{Array{Int64,N} where N,N} where N,1}:
 [[1, 2, 3]]

julia> a[1]
1-element Array{Array{Int64,N} where N,1}:
 [1, 2, 3]

julia> a[1][1]
3-element Array{Int64,1}:
 1
 2
 3
Sign up to request clarification or add additional context in comments.

2 Comments

thanks. could you explain how this translates into function signatures? is function process_array(s::Array{Array{Array{Int64,1},1},1}) the proper way to say the function takes an array of array of arrays of int? Why is 1 dimension necessary to be there explicitly and not just Array{Array{Array{Int64}}}}
I hope @DNF explained why 1 appears in the above very well (and you should generally use Vector and Matrix unless you need objects of higher dimensionality). Now regarding the signatures if you write T[] then a function call that accepts this value should be specified as f(::Vector{T}) (so essentially in function call you have an additional Vector on top of what you specify when constructing an object).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.