Skip to content

Commit

Permalink
add back last for every type that defines Iterators.reverse
Browse files Browse the repository at this point in the history
  • Loading branch information
vtjnash authored and LilithHafner committed Feb 22, 2022
1 parent aee8fdc commit 2947c47
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 2 deletions.
1 change: 1 addition & 0 deletions base/generator.jl
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ size(g::Generator) = size(g.iter)
axes(g::Generator) = axes(g.iter)
ndims(g::Generator) = ndims(g.iter)
keys(g::Generator) = keys(g.iter)
last(g::Generator) = g.f(last(g.iter))


## iterator traits
Expand Down
13 changes: 12 additions & 1 deletion base/iterators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ size(e::Enumerate) = size(e.itr)
n === nothing && return n
(i, n[1]), (i+1, n[2])
end
last(e::Enumerate) = (length(e.itr), e.itr[end])

eltype(::Type{Enumerate{I}}) where {I} = Tuple{Int, eltype(I)}

Expand Down Expand Up @@ -251,6 +252,10 @@ IteratorSize(::Type{<:Pairs{<:Any, <:Any, I}}) where {I} = IteratorSize(I)
IteratorSize(::Type{<:Pairs{<:Any, <:Any, <:Base.AbstractUnitRange, <:Tuple}}) = HasLength()

reverse(v::Pairs) = Pairs(getfield(v, :data), reverse(getfield(v, :itr)))
function last(v::Pairs{K, V}) where {K, V}
idx = last(getfield(v, :itr))
return Pair{K, V}(idx, v[idx])
end

haskey(v::Pairs, key) = (key in getfield(v, :itr))
keys(v::Pairs) = getfield(v, :itr)
Expand Down Expand Up @@ -398,7 +403,8 @@ zip_iteratoreltype() = HasEltype()
zip_iteratoreltype(a) = a
zip_iteratoreltype(a, tail...) = and_iteratoreltype(a, zip_iteratoreltype(tail...))

reverse(z::Zip) = Zip(Base.map(reverse, z.is))
reverse(z::Zip) = Zip(Base.map(reverse, z.is)) # n.b. we assume all iterators are the same length
last(z::Zip) = getindex.(z.is, minimum(Base.map(lastindex, z.is)))

# filter

Expand Down Expand Up @@ -457,6 +463,7 @@ IteratorEltype(::Type{Filter{F,I}}) where {F,I} = IteratorEltype(I)
IteratorSize(::Type{<:Filter}) = SizeUnknown()

reverse(f::Filter) = Filter(f.flt, reverse(f.itr))
last(f::Filter) = first(reverse(f))

# Accumulate -- partial reductions of a function over an iterator

Expand Down Expand Up @@ -883,6 +890,7 @@ function iterate(it::Cycle, state)
end

reverse(it::Cycle) = Cycle(reverse(it.xs))
last(it::Cycle) = last(it.xs)

# Repeated - repeat an object infinitely many times

Expand Down Expand Up @@ -921,6 +929,7 @@ IteratorSize(::Type{<:Repeated}) = IsInfinite()
IteratorEltype(::Type{<:Repeated}) = HasEltype()

reverse(it::Union{Repeated,Take{<:Repeated}}) = it
last(it::Union{Repeated,Take{<:Repeated}}) = first(it)

# Product -- cartesian product of iterators
struct ProductIterator{T<:Tuple}
Expand Down Expand Up @@ -1052,6 +1061,7 @@ end
end

reverse(p::ProductIterator) = ProductIterator(Base.map(reverse, p.iterators))
last(p::ProductIterator) = Base.map(last, p.iterators)

# flatten an iterator of iterators

Expand Down Expand Up @@ -1131,6 +1141,7 @@ length(f::Flatten{Tuple{}}) = 0
end

reverse(f::Flatten) = Flatten(reverse(itr) for itr in reverse(f.it))
last(f::Flatten) = last(last(f.it))

"""
partition(collection, n)
Expand Down
14 changes: 13 additions & 1 deletion test/iterators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -689,11 +689,18 @@ end
Iterators.Filter(isodd, 1:10), flatten((1:10, 50:60)), enumerate("foo"),
pairs(50:60), zip(1:10,21:30,51:60), product(1:3, 10:12), repeated(3.14159, 5),
(a=2, b=3, c=5, d=7, e=11))
@test squash(collect(Iterators.reverse(itr))) == reverse(squash(collect(itr)))
arr = reverse(squash(collect(itr)))
itr = Iterators.reverse(itr)
@test squash(collect(itr)) == arr
if !isempty(arr)
@test first(itr) == first(arr)
@test last(itr) == last(arr)
end
end
@test collect(take(Iterators.reverse(cycle(1:3)), 7)) == collect(take(cycle(3:-1:1), 7))
let r = repeated(3.14159)
@test Iterators.reverse(r) === r
@test last(r) === 3.14159
end
for t in [(1,), (2, 3, 5, 7, 11), (a=1,), (a=2, b=3, c=5, d=7, e=11)]
@test Iterators.reverse(Iterators.reverse(t)) === t
Expand Down Expand Up @@ -887,3 +894,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

0 comments on commit 2947c47

Please sign in to comment.