From 66c3717c65c8d39c98f2a9bb258bc619db190356 Mon Sep 17 00:00:00 2001 From: Rafael Fourquet Date: Thu, 11 Jun 2020 11:21:17 +0200 Subject: [PATCH] allow passing multiple arguments to append! & prepend! 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)`. --- NEWS.md | 2 ++ base/array.jl | 37 ++++++++++++++++++++++++++++++------- test/arrayops.jl | 8 ++++++++ 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/NEWS.md b/NEWS.md index c920c63e5163c..a25824b20abe5 100644 --- a/NEWS.md +++ b/NEWS.md @@ -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 ------------------------ diff --git a/base/array.jl b/base/array.jl index c88dd8cba5878..5662602cac5ee 100644 --- a/base/array.jl +++ b/base/array.jl @@ -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 @@ -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) @@ -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 @@ -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) diff --git a/test/arrayops.jl b/test/arrayops.jl index 59eae3409f601..526c9fa37c41d 100644 --- a/test/arrayops.jl +++ b/test/arrayops.jl @@ -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]