Skip to content

Commit a7ed014

Browse files
committed
Make slices writable
1 parent c2728e5 commit a7ed014

3 files changed

Lines changed: 29 additions & 7 deletions

File tree

src/indexedarray.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ end
6767
"""
6868
unsafe_insertvar!(var::indexedVarArray{V,N,T}, index...)
6969
70-
Insert a new variable with the given index withouth checking if the index is valid or
70+
Insert a new variable with the given index without checking if the index is valid or
7171
already assigned.
7272
"""
7373
function unsafe_insertvar!(var::IndexedVarArray{V,N,T}, index...) where {V,N,T}

src/slice.jl

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,26 @@ function Base.getindex(v::SparseArraySlice{P,V,NF,MT}, idx...) where {P,V,NF,MT}
149149
return v[idx]
150150
end
151151

152-
function Base.setindex!(::SparseArraySlice, _, _...)
153-
return error("SparseArraySlice is read-only")
152+
# Forward mutation to parent array
153+
function Base.setindex!(
154+
v::SparseArraySlice{P,V,NF,MT},
155+
val,
156+
free_key::Tuple,
157+
) where {P,V,NF,MT}
158+
length(free_key) == NF || throw(BoundsError(v, free_key))
159+
T = _keytype(P)
160+
v.parent[_reconstruct_key(v.mask, free_key, T)] = val
161+
return val
162+
end
163+
164+
# Splatted version
165+
function Base.setindex!(
166+
v::SparseArraySlice{P,V,NF,MT},
167+
val,
168+
idx...,
169+
) where {P,V,NF,MT}
170+
length(idx) == NF || throw(BoundsError(v, idx))
171+
return setindex!(v, val, idx)
154172
end
155173

156174
function Base.size(::SparseArraySlice)

test/runtests.jl

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -396,16 +396,20 @@ const _test_sa = testdata_sa()
396396
@test Base.IteratorSize(typeof(v)) == Base.HasLength()
397397
@test Base.IteratorEltype(typeof(v)) == Base.HasEltype()
398398

399+
# setindex
400+
v2["bmw", 2002] = 200
401+
@test v2["bmw", 2002] == 200
402+
@test sa["bmw", 2002] == 200
403+
v2[("bmw", 2002)] = 300
404+
@test v2[("bmw", 2002)] == 300
405+
@test sa[("bmw", 2002)] == 300
406+
399407
# show / summary
400408
@test occursin("SparseArraySlice", sprint(summary, v))
401409
@test occursin("matching (\"ford\", Colon())", sprint(summary, v))
402410
@test occursin("(2000,) => 100", sprint(show, MIME("text/plain"), v))
403411
@test occursin("(2001,) => 150", sprint(show, MIME("text/plain"), v))
404412

405-
# read-only
406-
@test_throws MethodError (v[(2000,)] = 999)
407-
@test_throws ErrorException size(v)
408-
409413
# wrong mask length
410414
@test_throws BoundsError slice(sa, "ford", :, :)
411415

0 commit comments

Comments
 (0)