Skip to content

Commit

Permalink
allow passing multiple arguments to append! & prepend! (JuliaLang#36227)
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 Oct 11, 2020
1 parent 113afd9 commit 0c5329c
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 7 deletions.
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ New library features
* New constructor `NamedTuple(iterator)` that constructs a named tuple from a key-value pair iterator.
* A new `reinterpret(reshape, T, a::AbstractArray{S})` reinterprets `a` to have eltype `T` while potentially
inserting or consuming the first dimension depending on the ratio of `sizeof(T)` and `sizeof(S)`.
* New `append!(vector, collections...)` and `prepend!(vector, collections...)` methods accept multiple
collections to be appended or prepended ([#36227]).

Standard library changes
------------------------
Expand Down
37 changes: 30 additions & 7 deletions base/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -944,19 +944,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 Vector{Int64}:
1
2
3
julia> append!([1, 2, 3], [4, 5, 6])
julia> append!([1, 2, 3], [4, 5], [6])
6-element Vector{Int64}:
1
2
Expand All @@ -981,6 +985,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 @@ -999,17 +1005,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 Vector{Int64}:
1
2
3
julia> prepend!([6], [1, 2], [3, 4, 5])
6-element Vector{Int64}:
1
2
3
4
5
6
```
"""
function prepend! end
Expand All @@ -1029,6 +1050,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 @@ -1613,6 +1613,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 0c5329c

Please sign in to comment.