Is there a sparse array with 'missing' as default

something like :

[missing,1.5,missing,missing]

where only 2 => 1.5 is stored?

Depending on your needs, get could work well for you here:

julia> d = Dict{Int,Float64}(2 => 1.5)
Dict{Int64, Float64} with 1 entry:
  2 => 1.5

julia> get(d, 1, missing)
missing

julia> get(d, 2, missing)
1.5

julia> get(d, 3, missing)
missing

If you want this wrapped in an AbstractArray, then you can implement an array interface wrapper for it. Like this:

struct SparseFillArray{T, U, D} <: AbstractArray{Union{T, U}, D}
	dat::Dict{Int, T}
	fillval::U
	sz::NTuple{D, Int}
end

Base.IndexStyle(::Type{<:SparseFillArray}) = IndexLinear()

Base.size(A::SparseFillArray) = A.sz

function Base.getindex(A::SparseFillArray, i::Int)
	1 <= i <= length(A) || Base.throw_boundserror(A, (i,))
	return get(A.dat, i, A.fillval)
end

function Base.setindex!(A::SparseFillArray, val, i::Int)
	1 <= i <= length(A) || Base.throw_boundserror(A, (i,))
	if isequal(A.fillval, val)
		delete!(A.dat, i)
	else
		A.dat[i] = val
	end
	return val
end
julia> x = SparseFillArray(Dict{Int, Float64}(), missing, (3,3))
3×3 SparseFillArray{Float64, Missing, 2}:
 missing  missing  missing
 missing  missing  missing
 missing  missing  missing

julia> x[2,1] = 1.5
1.5

julia> x
3×3 SparseFillArray{Float64, Missing, 2}:
  missing  missing  missing
 1.5       missing  missing
  missing  missing  missing

julia> x.dat
Dict{Int64, Float64} with 1 entry:
  2 => 1.5

You could hardcode the fillval to be missing, but here I kept it general.

5 Likes