From e753cc07094d3cc25b02963ab3aedfa731edd901 Mon Sep 17 00:00:00 2001 From: rofinn Date: Tue, 19 Nov 2019 18:20:23 -0600 Subject: [PATCH 1/3] Add a firstrest function. --- docs/src/index.md | 7 +++++++ src/IterTools.jl | 22 ++++++++++++++++++++++ test/runtests.jl | 7 +++++++ 3 files changed, 36 insertions(+) diff --git a/docs/src/index.md b/docs/src/index.md index 36d064c..176af24 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -20,6 +20,13 @@ Iterate through values skipping over those already encountered. distinct ``` +## firstrest(xs) + +Return first element and `Iterators.rest` iterator as a tuple. +```@docs +firstrest +``` + ## groupby(f, xs) Group consecutive values that share the same result of applying `f`. diff --git a/src/IterTools.jl b/src/IterTools.jl index 5b6b468..6b26274 100644 --- a/src/IterTools.jl +++ b/src/IterTools.jl @@ -9,6 +9,7 @@ import Base: SizeUnknown, IsInfinite, HasLength, HasShape import Base: HasEltype, EltypeUnknown export + firstrest, takestrict, repeatedly, chain, @@ -84,6 +85,27 @@ macro ifsomething(ex) end end +""" + firstrest(xs) -> (f, r) + +Return the first element and an iterator of the rest as a tuple. + +```jldoctest +julia> f, r = firstrest(1:3) +(1, Base.Iterators.Rest{UnitRange{Int64},Int64}(1:3, 1)) + +julia> collect(r) +2-element Array{Int64,1}: + 2 + 3 +``` +""" +function firstrest(xs) + f, s = iterate(xs) + r = Iterators.rest(xs, s) + return f, r +end + # Iterate through the first n elements, throwing an exception if # fewer than n items ar encountered. diff --git a/test/runtests.jl b/test/runtests.jl index 383fec0..bcd48b2 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -10,6 +10,13 @@ include("testing_macros.jl") @testset "IterTools" begin @testset "iterators" begin + @testset "firstrest" begin + iter = 1:10 + f, r = firstrest(iter) + @test f == 1 + @test collect(r) == collect(2:10) + end + @testset "takestrict" begin itr = 1:10 take_itr = takestrict(itr, 5) From 4598d498c2756039f320f14799218d871fffcbb6 Mon Sep 17 00:00:00 2001 From: rofinn Date: Wed, 20 Nov 2019 12:38:57 -0600 Subject: [PATCH 2/3] More firstrest tests and handle empty case. --- src/IterTools.jl | 4 +++- test/runtests.jl | 31 +++++++++++++++++++++++++++---- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/IterTools.jl b/src/IterTools.jl index 6b26274..fec84c0 100644 --- a/src/IterTools.jl +++ b/src/IterTools.jl @@ -101,7 +101,9 @@ julia> collect(r) ``` """ function firstrest(xs) - f, s = iterate(xs) + t = iterate(xs) + t === nothing && throw(ArgumentError("collection must be non-empty")) + f, s = t r = Iterators.rest(xs, s) return f, r end diff --git a/test/runtests.jl b/test/runtests.jl index bcd48b2..f7c5992 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -11,10 +11,33 @@ include("testing_macros.jl") @testset "IterTools" begin @testset "iterators" begin @testset "firstrest" begin - iter = 1:10 - f, r = firstrest(iter) - @test f == 1 - @test collect(r) == collect(2:10) + # We ranges/generators have different rest states vs array/tuples + test_base_cases = [ + (1:1, 1), + (1:3, 1), + ([1], 2), + ([1, 2, 3], 2), + ((1,), 2), + ((1, 2, 3), 2), + ((i for i in 1:1), 1), + ((i for i in 1:3), 1), + ] + @testset "$xs" for (xs, s) in test_base_cases + f, r = firstrest(xs) + @test f == first(xs) + @test collect(r) == collect(Iterators.rest(xs, s)) + end + + test_empty_cases = [ + (1:0, 1), + (Int[], 2), + ((), 2), + ((i for i in 1:0), 1), + ] + + @testset "$xs" for (xs, s) in test_empty_cases + @test_throws ArgumentError firstrest(xs) + end end @testset "takestrict" begin From 446685b17acac5732340436ce54b8b3a799cd492 Mon Sep 17 00:00:00 2001 From: Rory Finnegan Date: Wed, 20 Nov 2019 13:32:04 -0600 Subject: [PATCH 3/3] Update test/runtests.jl Co-Authored-By: Eric Davies --- test/runtests.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/runtests.jl b/test/runtests.jl index f7c5992..f13ccab 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -11,7 +11,7 @@ include("testing_macros.jl") @testset "IterTools" begin @testset "iterators" begin @testset "firstrest" begin - # We ranges/generators have different rest states vs array/tuples + # Ranges/generators have different rest states vs array/tuples test_base_cases = [ (1:1, 1), (1:3, 1),