# Vectors with different out-of-bounds behavior

Consider integer vectors, Ivect(n) = Vector{Int}(undef, n).

If you access a vector A = Ivect(n) with indices < 1 or > n,
a BoundsError is thrown.

How can you introduce an integer vector type that simply returns 0 in these cases?

There are in fact just two functions you must define for your struct to behave like an array:

``````struct Zeroed{T,N,AT} <: AbstractArray{T,N}
data::AT
Zeroed(data::AT) where {AT<:AbstractArray{T,N}} where {T,N} = new{T,N,AT}(data)
end
Base.size(A::Zeroed) = size(A.data)
Base.getindex(A::Zeroed, ij...) = all(in.(ij, axes(A.data))) ?
getindex(A.data, ij...) : zero(eltype(A))

Zeroed(rand(3,4))[3,100] == 0
``````
1 Like

Thanks, looks good, but exceeds my understanding. It would be enough if I got something like that going:

``````struct Ivect <: AbstractArray
data::Vector{Int}
function Ivect(n::Int)
new(Vector{Int}(undef, n))
end
end
Base.size(A::Ivect) = size(A.data)
Base.getindex(A::Ivect, n) = (n < 1 || n > size(A)) ? Int(0) :
getindex(A.data, n)

A = Ivect(5); for i in 1:size(A) (A[i] = i) end
println(A, " ", A[end], " ", A[end+1])``````

This should almost work too, you need `struct Ivect <: AbstractArray{Int,1}` and I think you want `n > length(A)` in getindex. To write into the array, you also need

``````Base.setindex!(A::Ivect, val, i::Int) = A.data[i] = val
``````

Then `A = Ivect(3); A = 33; [A[i] for i in 0:10]` should work.

1 Like

Great! Thanks! Now I can start studying your first, sophisticated, solution.

You could also just use `get` instead, e.g.:

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

julia> get(a, 2, 0)
2

julia> get(a, 5, 0)
0

julia> get(a, -1, 0)
0
``````
3 Likes