@@ -15,7 +15,6 @@ using .Base:
15
15
LinearIndices, (:), | , + , - , != = , ! , <= , < , missing , any, _counttuple
16
16
17
17
import . Base:
18
- first, last,
19
18
isempty, length, size, axes, ndims,
20
19
eltype, IteratorSize, IteratorEltype,
21
20
haskey, keys, values, pairs,
@@ -102,8 +101,8 @@ length(r::Reverse) = length(r.itr)
102
101
size (r:: Reverse ) = size (r. itr)
103
102
IteratorSize (:: Type{Reverse{T}} ) where {T} = IteratorSize (T)
104
103
IteratorEltype (:: Type{Reverse{T}} ) where {T} = IteratorEltype (T)
105
- last (r:: Reverse ) = first (r. itr) # the first shall be last
106
- first (r:: Reverse ) = last (r. itr) # and the last shall be first
104
+ Base . last (r:: Reverse ) = Base . first (r. itr) # the first shall be last
105
+ Base . first (r:: Reverse ) = Base . last (r. itr) # and the last shall be first
107
106
108
107
# reverse-order array iterators: assumes more-specialized Reverse for eachindex
109
108
@propagate_inbounds function iterate (A:: Reverse{<:AbstractArray} , state= (reverse (eachindex (A. itr)),))
@@ -986,8 +985,8 @@ iterate(::ProductIterator{Tuple{}}, state) = nothing
986
985
987
986
@inline isdone (P:: ProductIterator ) = any (isdone, P. iterators)
988
987
@inline function _pisdone (iters, states)
989
- iter1 = first (iters)
990
- done1 = isdone (iter1, first (states)[2 ]) # check step
988
+ iter1 = Base . first (iters)
989
+ done1 = isdone (iter1, Base . first (states)[2 ]) # check step
991
990
done1 === true || return done1 # false or missing
992
991
done1 = isdone (iter1) # check restart
993
992
done1 === true || return done1 # false or missing
@@ -1012,8 +1011,8 @@ end
1012
1011
1013
1012
@inline _piterate1 (:: Tuple{} , :: Tuple{} ) = nothing
1014
1013
@inline function _piterate1 (iters, states)
1015
- iter1 = first (iters)
1016
- next = iterate (iter1, first (states)[2 ])
1014
+ iter1 = Base . first (iters)
1015
+ next = iterate (iter1, Base . first (states)[2 ])
1017
1016
restnext = tail (states)
1018
1017
if next === nothing
1019
1018
isdone (iter1) === true && return nothing
@@ -1335,9 +1334,89 @@ only(x::Tuple) = throw(
1335
1334
ArgumentError (" Tuple contains $(length (x)) elements, must contain exactly 1 element" )
1336
1335
)
1337
1336
only (a:: AbstractArray{<:Any, 0} ) = @inbounds return a[]
1338
- only (x:: NamedTuple{<:Any, <:Tuple{Any}} ) = first (x)
1337
+ only (x:: NamedTuple{<:Any, <:Tuple{Any}} ) = Base . first (x)
1339
1338
only (x:: NamedTuple ) = throw (
1340
1339
ArgumentError (" NamedTuple contains $(length (x)) elements, must contain exactly 1 element" )
1341
1340
)
1342
1341
1342
+ """
1343
+ Iterators.first(coll)
1344
+
1345
+ Return the first element of iterable `coll` wrapped in [`Some`](@ref).
1346
+
1347
+ If `coll` is empty, return `nothing`.
1348
+
1349
+ See also [`something`](@ref), [`Iterators.last`](@ref).
1350
+
1351
+ !!! compat "Julia 1.6"
1352
+ This function was added in Julia 1.6.
1353
+
1354
+ # Extended help
1355
+
1356
+ This differs from [`first`](@ref) by not throwing an error for empty
1357
+ iterables. It can be used with [`Iterators.filter`](@ref) to safely
1358
+ get the first element of an iterable which matches a condition. With
1359
+ [`first`](@ref), this use requires handling collections with no
1360
+ elements matching the condition by catching the thrown
1361
+ [`BoundsError`](@ref).
1362
+
1363
+ # Examples
1364
+ ```jldoctest
1365
+ julia> Iterators.first(Iterators.filter(>(5), 1:10))
1366
+ Some(6)
1367
+
1368
+ julia> isnothing(Iterators.first(Iterators.filter(isodd, 2:2:10)))
1369
+ true
1370
+
1371
+ julia> something(Iterators.first(Iterators.filter(iseven, [5, 3, 4, 2, 6, 8])))
1372
+ 4
1373
+
1374
+ julia> something(Iterators.first(Iterators.filter(>(10), 1:10)), 0)
1375
+ 0
1376
+ ```
1377
+ """
1378
+ function first (itr)
1379
+ x = iterate (itr)
1380
+ x === nothing && return
1381
+ return Some (x[1 ])
1382
+ end
1383
+
1384
+ """
1385
+ Iterators.last(coll)
1386
+
1387
+ Return the last element of iterable `coll` wrapped in [`Some`](@ref).
1388
+
1389
+ If `coll` is empty, return `nothing`.
1390
+
1391
+ See also [`something`](@ref), [`Iterators.first`](@ref).
1392
+
1393
+ !!! compat "Julia 1.6"
1394
+ This function was added in Julia 1.6.
1395
+
1396
+ # Extended help
1397
+
1398
+ This differs from [`last`](@ref) by not throwing an error for empty
1399
+ iterables. It can be used with [`Iterators.filter`](@ref) to safely
1400
+ get the last element of an iterable which matches a condition. With
1401
+ [`last`](@ref), this use requires handling collections with no
1402
+ elements matching the condition by catching the thrown
1403
+ [`BoundsError`](@ref).
1404
+
1405
+ # Examples
1406
+ ```jldoctest
1407
+ julia> Iterators.last(Iterators.filter(<(5), 1:10))
1408
+ Some(4)
1409
+
1410
+ julia> isnothing(Iterators.last(Iterators.filter(isodd, 2:2:10)))
1411
+ true
1412
+
1413
+ julia> something(Iterators.last(Iterators.filter(iseven, [5, 3, 4, 2, 6, 9])))
1414
+ 6
1415
+
1416
+ julia> something(Iterators.last(Iterators.filter(>(10), 1:10)), 0)
1417
+ 0
1418
+ ```
1419
+ """
1420
+ last (itr) = first (reverse (itr))
1421
+
1343
1422
end
0 commit comments