Skip to content

Commit

Permalink
allow passing multiple arguments to append! & prepend!
Browse files Browse the repository at this point in the history
E.g. append!([1], [2], [3]) == [1, 2, 3].
The equivalent operation for sets (`union!`) and dictionaries (`merge!`)
already supports multiple arguments, as well as `push!`.

For `prepend!`, order is maintained in the same way as in `pushfirst!`:
`prepend!([3], [1], [2]) == [1, 2, 3] == pushfirst!([3], 1, 2)`.
  • Loading branch information
rfourquet committed Jun 11, 2020
1 parent 70d8497 commit 47733ed
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 7 deletions.
37 changes: 30 additions & 7 deletions base/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -946,19 +946,23 @@ function push!(a::Array{Any,1}, @nospecialize item)
end

"""
append!(collection, collection2) -> collection.
append!(collection, collections...) -> collection.
For an ordered container `collection`, add the elements of `collection2` to the end of it.
For an ordered container `collection`, add the elements of each `collections`
to the end of it.
!!! compat "Julia 1.6"
Specifying multiple collections to be appended requires at least Julia 1.6.
# Examples
```jldoctest
julia> append!([1],[2,3])
julia> append!([1], [2, 3])
3-element Array{Int64,1}:
1
2
3
julia> append!([1, 2, 3], [4, 5, 6])
julia> append!([1, 2, 3], [4, 5], [6])
6-element Array{Int64,1}:
1
2
Expand All @@ -983,6 +987,8 @@ end
append!(a::AbstractVector, iter) = _append!(a, IteratorSize(iter), iter)
push!(a::AbstractVector, iter...) = append!(a, iter)

append!(a::AbstractVector, iter...) = foldl(append!, iter, init=a)

function _append!(a, ::Union{HasLength,HasShape}, iter)
n = length(a)
i = lastindex(a)
Expand All @@ -1001,17 +1007,32 @@ function _append!(a, ::IteratorSize, iter)
end

"""
prepend!(a::Vector, items) -> collection
prepend!(a::Vector, collections...) -> collection
Insert the elements of each `collections` to the beginning of `a`.
When `collections` specifies multiple collections, order is maintained:
elements of `collections[1]` will appear leftmost in `a`, and so on.
Insert the elements of `items` to the beginning of `a`.
!!! compat "Julia 1.6"
Specifying multiple collections to be prepended requires at least Julia 1.6.
# Examples
```jldoctest
julia> prepend!([3],[1,2])
julia> prepend!([3], [1, 2])
3-element Array{Int64,1}:
1
2
3
julia> prepend!([6], [1, 2], [3, 4, 5])
6-element Array{Int64,1}:
1
2
3
4
5
6
```
"""
function prepend! end
Expand All @@ -1031,6 +1052,8 @@ end
prepend!(a::Vector, iter) = _prepend!(a, IteratorSize(iter), iter)
pushfirst!(a::Vector, iter...) = prepend!(a, iter)

prepend!(a::AbstractVector, iter...) = foldr((v, a) -> prepend!(a, v), iter, init=a)

function _prepend!(a, ::Union{HasLength,HasShape}, iter)
require_one_based_indexing(a)
n = length(iter)
Expand Down
8 changes: 8 additions & 0 deletions test/arrayops.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1576,6 +1576,14 @@ end
@test append!([1,2], g) == [1,2] == push!([1,2], g...)
@test prepend!([1,2], g) == [1,2] == pushfirst!([1,2], g...)

# multiple items
A = [1]
@test append!(A, [2, 3], [4], [5, 6]) === A
@test A == [1, 2, 3, 4, 5, 6]
A = [1]
@test prepend!(A, [2, 3], [4], [5, 6]) === A
@test A == [2, 3, 4, 5, 6, 1]

# offset array
@test append!([1,2], OffsetArray([9,8], (-3,))) == [1,2,9,8]
@test prepend!([1,2], OffsetArray([9,8], (-3,))) == [9,8,1,2]
Expand Down

0 comments on commit 47733ed

Please sign in to comment.