Indexing 1-Dimentional Arrays

Hello.

I was reading Julia’s manual (Section: Noteworthy differences) and came across this quote.

Julia has true one-dimensional arrays. Column vectors are of size N , not Nx1 . For example, rand(N) makes a 1-dimensional array.

It is true that

A = Array{Int8,1}(undef, 3)

B = Array{Int8,2}(undef, 3,1)

C = Array{Int8,2}(undef, 1,3)

are all different types of Array. But why is it possible to eval for example

julia> A[2,1]
-35

if A has 1 dimension only?

There is a convention that a scalar value can be used in the same way as an N-dimensional array, provided that it is always accessed at index 1:

julia> x = 42
42

julia> x[1]
42

julia> x[1, 1]
42

julia> x[1, 1, 1]
42

The above works, because all non-existing axes are accessed only at index 1. As soon as you try to access another index, you get an out-of-bounds error:

julia> x[2]
ERROR: BoundsError
Stacktrace:
 [1] getindex(::Int64, ::Int64) at ./number.jl:78
 [2] top-level scope at REPL[13]:1

julia> x[1, 2]
ERROR: BoundsError
Stacktrace:
 [1] getindex(::Int64, ::Int64, ::Int64) at ./number.jl:83
 [2] top-level scope at REPL[14]:1

In the same way, any N-dimensional array can be used as an M-dimensional array (with M>N), provided that all extra axes are accessed at index 1. These all work:

julia> A = rand(10);

julia> A[2,1]
0.9346414306362032

julia> A[2,1,1]
0.9346414306362032

but the following does not:

julia> A[2,2]
ERROR: BoundsError: attempt to access 10-element Array{Float64,1} at index [2, 2]
Stacktrace:
 [1] getindex(::Array{Float64,1}, ::Int64, ::Int64) at ./array.jl:729
 [2] top-level scope at REPL[18]:1

This is documented with more details in

https://docs.julialang.org/en/v1/manual/arrays/#Omitted-and-extra-indices-1

5 Likes

Thanks for the explanation.

I was a little surprised recently that this works for zero-dimensional Arrays but not for Ref:

julia> fill(0)[1] # zero-array
0

julia> fill(0)[1,1]
0

julia> Ref(0)[1] # ndims(Ref(0)) == 0 too
ERROR: MethodError: no method matching getindex(::Base.RefValue{Int64}, ::Int64)

julia> (0,)[1,1]
ERROR: MethodError: no method matching getindex(::Tuple{Int64}, ::Int64, ::Int64)

Since RefValue is not an AbstractArray, there is no reason to expect that it would support the interface for the latter.