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?

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[0], " ", 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[1] = 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