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
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.
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