diff --git a/src/utils.jl b/src/utils.jl index 6a8cb81e..6f548a2a 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -214,36 +214,19 @@ end # helpers to figure out if there are NaN values in a list of array types anynan(i::Int, args::Tuple) = any(a -> try isnan(_cycle(a,i)) catch MethodError false end, args) -anynan(istart::Int, iend::Int, args::Tuple) = any(i -> anynan(i, args), istart:iend) -allnan(istart::Int, iend::Int, args::Tuple) = all(i -> anynan(i, args), istart:iend) +anynan(args::Tuple) = i -> anynan(i,args) +anynan(istart::Int, iend::Int, args::Tuple) = any(anynan(args), istart:iend) +allnan(istart::Int, iend::Int, args::Tuple) = all(anynan(args), istart:iend) function Base.iterate(itr::SegmentsIterator, nextidx::Int = 1) - nextidx > itr.n && return nothing - if nextidx == 1 && !any(isempty,itr.args) && anynan(1, itr.args) - nextidx = 2 - end + i = findfirst(!anynan(itr.args), nextidx:itr.n) + i === nothing && return nothing + nextval = nextidx + i - 1 - i = istart = iend = nextidx + j = findfirst(anynan(itr.args), nextval:itr.n) + nextnan = j === nothing ? itr.n + 1 : nextval + j - 1 - # find the next NaN, and iend is the one before - while i <= itr.n + 1 - if i > itr.n || anynan(i, itr.args) - # done... array end or found NaN - iend = i-1 - break - end - i += 1 - end - - # find the next non-NaN, and set nextidx - while i <= itr.n - if !anynan(i, itr.args) - break - end - i += 1 - end - - istart:iend, i + nextval:nextnan-1, nextnan end # Find minimal type that can contain NaN and x diff --git a/test/runtests.jl b/test/runtests.jl index 8e6ef9c1..e2f7b9c5 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -51,5 +51,31 @@ end end @testset "NoFail" begin - histogram([1, 0, 0, 0, 0, 0]) + plots = [histogram([1, 0, 0, 0, 0, 0]), + plot([missing]), + plot([missing; 1:4]), + plot([fill(missing,10); 1:4])] + for plt in plots + display(plt) + end +end + +@testset "Segments" begin + function segments(args...) + segs = UnitRange{Int}[] + for seg in iter_segments(args...) + push!(segs,seg) + end + segs + end + + nan10 = fill(NaN,10) + @test segments(11:20) == [1:10] + @test segments([NaN]) == [] + @test segments(nan10) == [] + @test segments([nan10; 1:5]) == [11:15] + @test segments([1:5;nan10]) == [1:5] + @test segments([nan10; 1:5; nan10; 1:5; nan10]) == [11:15, 26:30] + @test segments([NaN; 1], 1:10) == [2:2, 4:4, 6:6, 8:8, 10:10] + @test segments([nan10; 1:15], [1:15; nan10]) == [11:15] end