Skip to content

Commit

Permalink
replace delete! with splice! for arrays. fixes #3023
Browse files Browse the repository at this point in the history
also adds the ability to replace the deleted items with a third argument
  • Loading branch information
JeffBezanson committed May 31, 2013
1 parent 5ec7bc0 commit 4119af9
Show file tree
Hide file tree
Showing 13 changed files with 110 additions and 53 deletions.
85 changes: 62 additions & 23 deletions base/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -760,48 +760,87 @@ function insert!{T}(a::Array{T,1}, i::Integer, item)
a[i] = item
end

function delete!(a::Vector, i::Integer)
const _default_splice = []

function splice!(a::Vector, i::Integer, ins::AbstractArray=_default_splice)
n = length(a)
if !(1 <= i <= n)
throw(BoundsError())
end
v = a[i]
if i < div(n,2)
for k = i:-1:2
a[k] = a[k-1]
m = length(ins)
if m == 0
if i < div(n,2)
for k = i:-1:2
a[k] = a[k-1]
end
ccall(:jl_array_del_beg, Void, (Any, Uint), a, 1)
else
for k = i:n-1
a[k] = a[k+1]
end
ccall(:jl_array_del_end, Void, (Any, Uint), a, 1)
end
ccall(:jl_array_del_beg, Void, (Any, Uint), a, 1)
elseif m == 1
a[i] = ins[1]
else
for k = i:n-1
a[k] = a[k+1]
if i < div(n,2)
ccall(:jl_array_grow_beg, Void, (Any, Uint), a, m-1)
for k = 1:i-1
a[k] = a[k+m-1]
end
else
ccall(:jl_array_grow_end, Void, (Any, Uint), a, m-1)
for k = n+m-1:-1:(i+1+(m-1))
a[k] = a[k-(m-1)]
end
end
for k = 1:m
a[i+k-1] = ins[k]
end
ccall(:jl_array_del_end, Void, (Any, Uint), a, 1)
end
return v
end

function delete!{T<:Integer}(a::Vector, r::Range1{T})
function splice!{T<:Integer}(a::Vector, r::Range1{T}, ins::AbstractArray=_default_splice)
n = length(a)
f = first(r)
l = last(r)
if !(1 <= f && l <= n)
throw(BoundsError())
end
if l < f
return T[]
end
v = a[r]
d = l-f+1
if f-1 < n-l
for k = l:-1:1+d
a[k] = a[k-d]
end
ccall(:jl_array_del_beg, Void, (Any, Uint), a, d)
else
for k = f:n-d
a[k] = a[k+d]
v = a[r]
m = length(ins)
if m < d
delta = d - m
if f-1 < n-l
for k = l:-1:1+delta
a[k] = a[k-delta]
end
ccall(:jl_array_del_beg, Void, (Any, Uint), a, delta)
else
for k = f:n-delta
a[k] = a[k+delta]
end
ccall(:jl_array_del_end, Void, (Any, Uint), a, delta)
end
elseif m > d
delta = m - d
if f-1 < n-l
ccall(:jl_array_grow_beg, Void, (Any, Uint), a, delta)
for k = 1:f-1
a[k] = a[k+delta]
end
else
ccall(:jl_array_grow_end, Void, (Any, Uint), a, delta)
for k = n+delta:-1:(l+1+delta)
a[k] = a[k-delta]
end
end
ccall(:jl_array_del_end, Void, (Any, Uint), a, d)
end
for k = 1:m
a[f+k-1] = ins[k]
end
return v
end
Expand Down Expand Up @@ -1466,7 +1505,7 @@ function filter!(f::Function, a::Vector)
insrt += 1
end
end
delete!(a, insrt:length(a))
splice!(a, insrt:length(a))
return a
end

Expand Down
6 changes: 3 additions & 3 deletions base/bitarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -754,7 +754,7 @@ function resize!(B::BitVector, n::Integer)
end
n0 = length(B)
if n <= n0
delete!(B, n+1:n0)
splice!(B, n+1:n0)
return B
end
k0 = length(B.chunks)
Expand Down Expand Up @@ -855,7 +855,7 @@ function insert!(B::BitVector, i::Integer, item)
B[i] = item
end

function delete!(B::BitVector, i::Integer)
function splice!(B::BitVector, i::Integer)
n = length(B)
if !(1 <= i <= n)
throw(BoundsError())
Expand Down Expand Up @@ -890,7 +890,7 @@ function delete!(B::BitVector, i::Integer)
return v
end

function delete!(B::BitVector, r::Range1{Int})
function splice!(B::BitVector, r::Range1{Int})
n = length(B)
i_f = first(r)
i_l = last(r)
Expand Down
2 changes: 2 additions & 0 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,8 @@ export PipeString
@deprecate iscomplex(x) iseltype(x,Complex)
@deprecate lstrip(a::String, b::String) lstrip(a, collect(b))
@deprecate rstrip(a::String, b::String) rstrip(a, collect(b))
@deprecate delete!(a::Vector, x) splice!(a, x)
@deprecate delete!(a::BitVector, x) splice!(a, x)


# note removed macros: str, B_str, I_str, E_str, L_str, L_mstr, I_mstr, E_mstr
Expand Down
1 change: 1 addition & 0 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,7 @@ export
similar,
setdiff,
setdiff!,
splice!,
symdiff,
symdiff!,
union,
Expand Down
2 changes: 1 addition & 1 deletion base/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1990,7 +1990,7 @@ function tuple_elim_pass(ast::Expr)
continue
end

delete!(body, i) # remove tuple allocation
splice!(body, i) # remove tuple allocation
# convert tuple allocation to a series of local var assignments
vals = cell(nv)
n_ins = 0
Expand Down
12 changes: 6 additions & 6 deletions base/linalg/sparse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ function (*){Tv,Ti}(A::SparseMatrixCSC{Tv,Ti}, B::SparseMatrixCSC{Tv,Ti})
end
colptrC[nB+1] = ip

delete!(rowvalC, colptrC[end]:length(rowvalC))
delete!(nzvalC, colptrC[end]:length(nzvalC))
splice!(rowvalC, colptrC[end]:length(rowvalC))
splice!(nzvalC, colptrC[end]:length(nzvalC))

# The Gustavson algorithm does not guarantee the product to have sorted row indices.
return ((SparseMatrixCSC(mA, nB, colptrC, rowvalC, nzvalC).').')
Expand Down Expand Up @@ -222,8 +222,8 @@ function sparse_diff1{Tv,Ti}(S::SparseMatrixCSC{Tv,Ti})
end
colptr[col+1] = numnz+1
end
delete!(rowval, numnz+1:length(rowval))
delete!(nzval, numnz+1:length(nzval))
splice!(rowval, numnz+1:length(rowval))
splice!(nzval, numnz+1:length(nzval))
return SparseMatrixCSC{Tv,Ti}(m-1, n, colptr, rowval, nzval)
end

Expand Down Expand Up @@ -314,8 +314,8 @@ function sparse_diff2{Tv,Ti}(a::SparseMatrixCSC{Tv,Ti})

colptr[col+1] = ptrS
end
delete!(rowval, ptrS:length(rowval))
delete!(nzval, ptrS:length(nzval))
splice!(rowval, ptrS:length(rowval))
splice!(nzval, ptrS:length(nzval))
return SparseMatrixCSC{Tv,Ti}(m, n-1, colptr, rowval, nzval)
end

Expand Down
2 changes: 1 addition & 1 deletion base/multi.jl
Original file line number Diff line number Diff line change
Expand Up @@ -726,7 +726,7 @@ function deliver_result(sock::(), msg, oid, value)
job = j[2]
job.argument = value
enq_work(job)
delete!(jobs, i)
splice!(jobs, i)
break
end
end
Expand Down
2 changes: 1 addition & 1 deletion base/path.jl
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ function normpath(path::String)
clean = true
for j = 1:length(parts)-1
if parts[j] != ".." && parts[j+1] == ".."
delete!(parts, j:j+1)
splice!(parts, j:j+1)
clean = false
break
end
Expand Down
2 changes: 1 addition & 1 deletion base/printf.jl
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ function _parse(s::String)
end
list[i] *= list[j]
end
delete!(list,i+1:j)
splice!(list,i+1:j)
end
i += 1
end
Expand Down
12 changes: 6 additions & 6 deletions base/sparse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -501,8 +501,8 @@ for (op, restype) in ( (:+, Nothing), (:-, Nothing), (:.*, Nothing), (:.^, Nothi
colptrS[col+1] = ptrS
end

delete!(rowvalS, colptrS[end]:length(rowvalS))
delete!(nzvalS, colptrS[end]:length(nzvalS))
splice!(rowvalS, colptrS[end]:length(rowvalS))
splice!(nzvalS, colptrS[end]:length(nzvalS))
return SparseMatrixCSC(m, n, colptrS, rowvalS, nzvalS)
end

Expand Down Expand Up @@ -946,8 +946,8 @@ function setindex!{T,Ti}(A::SparseMatrixCSC{T,Ti}, v, i0::Integer, i1::Integer)
end
end
if loc != -1
delete!(A.rowval, loc)
delete!(A.nzval, loc)
splice!(A.rowval, loc)
splice!(A.nzval, loc)
for j = (i1+1):(A.n+1)
A.colptr[j] = A.colptr[j] - 1
end
Expand Down Expand Up @@ -1147,8 +1147,8 @@ function setindex!{Tv,Ti}(A::SparseMatrixCSC{Tv,Ti}, B::SparseMatrixCSC{Tv,Ti},
colB += 1
end

delete!(rowvalS, colptrS[end]:length(rowvalS))
delete!(nzvalS, colptrS[end]:length(nzvalS))
splice!(rowvalS, colptrS[end]:length(rowvalS))
splice!(nzvalS, colptrS[end]:length(nzvalS))

A.colptr = colptrS
A.rowval = rowvalS
Expand Down
15 changes: 10 additions & 5 deletions doc/stdlib/base.rst
Original file line number Diff line number Diff line change
Expand Up @@ -579,13 +579,18 @@ Dequeues

Insert an item at the given index.

.. function:: delete!(collection, index) -> item
.. function:: splice!(collection, index, [replacement]) -> item

Remove the item at the given index, and return the deleted item.
Remove the item at the given index, and return the removed item. Subsequent items
are shifted down to fill the resulting gap. If specified, replacement values from
an ordered collection will be spliced in place of the removed item.

.. function:: delete!(collection, range) -> items

Remove items at specified range, and return a collection containing the deleted items.
.. function:: splice!(collection, range, [replacement]) -> items

Remove items in the specified index range, and return a collection containing the
removed items. Subsequent items are shifted down to fill the resulting gap.
If specified, replacement values from an ordered collection will be spliced in place
of the removed items.

.. function:: resize!(collection, n) -> collection

Expand Down
10 changes: 10 additions & 0 deletions test/arrayops.jl
Original file line number Diff line number Diff line change
Expand Up @@ -445,3 +445,13 @@ end

# fill
@test fill!(Array(Float64,1),-0.0)[1] === -0.0

# splice!
for idx in {1, 2, 5, 9, 10, 1:0, 2:1, 1:1, 2:2, 1:2, 2:4, 9:8, 10:9, 9:9, 10:10,
8:9, 9:10, 6:9, 7:10}
for repl in {[], [11], [11,22], [11,22,33,44,55]}
a = [1:10]; acopy = copy(a)
@test splice!(a, idx, repl) == acopy[idx]
@test a == [acopy[1:(first(idx)-1)], repl, acopy[(last(idx)+1):end]]
end
end
12 changes: 6 additions & 6 deletions test/bitarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -180,17 +180,17 @@ b1 = randbool(v1)
i1 = bitunpack(b1)
for m = v1 : -1 : 1
j = rand(1:m)
delete!(b1, j)
delete!(i1, j)
splice!(b1, j)
splice!(i1, j)
@test isequal(bitunpack(b1), i1)
end
@test length(b1) == 0

b1 = randbool(v1)
i1 = bitunpack(b1)
for j in [63, 64, 65, 127, 128, 129, 191, 192, 193]
delete!(b1, j)
delete!(i1, j)
splice!(b1, j)
splice!(i1, j)
@test isequal(bitunpack(b1), i1)
end

Expand All @@ -200,8 +200,8 @@ for m1 = 1 : v1
for m2 = m1 : v1
b2 = copy(b1)
i2 = copy(i1)
delete!(b2, m1:m2)
delete!(i2, m1:m2)
splice!(b2, m1:m2)
splice!(i2, m1:m2)
@test isequal(bitunpack(b2), i2)
end
end
Expand Down

0 comments on commit 4119af9

Please sign in to comment.