Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make last work on reversible any collection #42991

Merged
merged 13 commits into from
Nov 10, 2021
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ Language changes
* `@time` and `@timev` now take an optional description to allow annotating the source of time reports.
i.e. `@time "Evaluating foo" foo()` ([#42431])
* New `@showtime` macro to show both the line being evaluated and the `@time` report ([#42431])
* `last(collection)` will now work on any collection that supports `Iterators.reverse` and `first`, rather than being
restricted to indexable collections.

Compiler/Runtime improvements
-----------------------------
Expand Down
12 changes: 8 additions & 4 deletions base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -461,12 +461,16 @@ end
"""
last(coll)

Get the last element of an ordered collection, if it can be computed in O(1) time. This is
accomplished by calling [`lastindex`](@ref) to get the last index. Return the end
point of an [`AbstractRange`](@ref) even if it is empty.
Get the last element of an ordered collection, if it can be computed by reversing the collection. This is
MasonProtter marked this conversation as resolved.
Show resolved Hide resolved
accomplished by calling [`Iterators.reverse`](@ref) and then [`first`](@ref) on that reversed iterator.
Return the end point of an [`AbstractRange`](@ref) even if it is empty.

See also [`first`](@ref), [`endswith`](@ref).

!!! compat "Julia 1.8"
For versions of julia older than 1.8, `last(x)` will only work on collections that support indexing and
[`lastindex`](@ref).

# Examples
```jldoctest
julia> last(1:2:10)
Expand All @@ -476,7 +480,7 @@ julia> last([1; 2; 3; 4])
4
```
"""
last(a) = a[end]
last(a) = first(Iterators.reverse(a))

"""
last(itr, n::Integer)
Expand Down
5 changes: 5 additions & 0 deletions test/iterators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -883,3 +883,8 @@ end
@test Iterators.peel(x^2 for x in 2:4)[1] == 4
@test Iterators.peel(x^2 for x in 2:4)[2] |> collect == [9, 16]
end

@testset "last for iterators" begin
@test last(Iterators.map(identity, 1:3)) == 3
@test last(Iterators.filter(iseven, (Iterators.map(identity, 1:3))) == 2
end