diff --git a/base/range.jl b/base/range.jl index 4ddecd7bdd91c1..b8c3024983e46b 100644 --- a/base/range.jl +++ b/base/range.jl @@ -1143,6 +1143,15 @@ function intersect(r::StepRange, s::StepRange) step(r) < zero(step(r)) ? StepRange{T,S}(n, -a, m) : StepRange{T,S}(m, a, n) end +function intersect(r1::AbstractRange, r2::AbstractRange) + if length(r2) < length(r1) + r1, r2 = r2, r1 + end + common = Iterators.filter(x -> x ∈ r2, r1) + seen = Set{eltype(vec)}(common) + return vectorfilter(_shrink_filter!(seen), common) +end + function intersect(r1::AbstractRange, r2::AbstractRange, r3::AbstractRange, r::AbstractRange...) i = intersect(intersect(r1, r2), r3) for t in r diff --git a/test/ranges.jl b/test/ranges.jl index 1c31585ece45e0..f930bfc83541cd 100644 --- a/test/ranges.jl +++ b/test/ranges.jl @@ -412,6 +412,19 @@ end @test intersect(start-Day(10):Day(1):stop-Day(10), start:Day(5):stop) == start:Day(5):stop-Day(10)-mod(stop-start, Day(5)) end + + @testset "Two AbstractRanges" begin + struct DummyRange{T} <: AbstractRange{T} + r + end + Base.iterate(dr::DummyRange) = iterate(dr.r) + Base.iterate(dr::DummyRange, state) = iterate(dr.r, state) + Base.length(dr::DummyRange) = length(dr.r) + Base.in(x::Int, dr::DummyRange) = in(x, dr.r) + r1 = DummyRange{Int}([1, 2, 3, 3, 4, 5]) + r2 = DummyRange{Int}([3, 3, 4, 5, 6]) + @test intersect(r1, r2) == [3, 4, 5] + end end @testset "issubset" begin @test issubset(1:3, 1:typemax(Int)) #32461