diff --git a/base/abstractset.jl b/base/abstractset.jl index f7399fdcd27dfe..41b23a9ca1767a 100644 --- a/base/abstractset.jl +++ b/base/abstractset.jl @@ -260,6 +260,8 @@ true """ issubset, ⊆, ⊇ +const FASTIN_SET_THRESHOLD = 70 + function issubset(l, r) if haslength(r) && (isa(l, AbstractSet) || !hasfastin(r)) rlen = length(r) # conditions above make this length computed only when needed @@ -269,7 +271,7 @@ function issubset(l, r) end # when `in` would be too slow and r is big enough, convert it to a Set # this threshold was empirically determined (cf. #26198) - if !hasfastin(r) && rlen > 70 + if !hasfastin(r) && rlen > FASTIN_SET_THRESHOLD return issubset(l, Set(r)) end end @@ -375,6 +377,30 @@ function issetequal(l, r) return issetequal(Set(l), Set(r)) end +## set disjoint comparison +""" + isdisjoint(v1, v2) -> Bool + +Returns whether the collections `v1` and `v2` are disjoint, i.e. whether +their intersection is empty. + +!!! compat "Julia 1.5" + This function requires at least Julia 1.5. +""" +function isdisjoint(l, r) + function _isdisjoint(l, r) + hasfastin(r) && return !any(in(r), l) + hasfastin(l) && return !any(in(l), r) + haslength(r) && length(r) < FASTIN_SET_THRESHOLD && + return !any(in(r), l) + return !any(in(Set(r)), l) + end + if haslength(l) && haslength(r) && length(r) < length(l) + return _isdisjoint(r, l) + end + _isdisjoint(l, r) +end + ## partial ordering of sets by containment ==(l::AbstractSet, r::AbstractSet) = length(l) == length(r) && l ⊆ r diff --git a/base/exports.jl b/base/exports.jl index 90e177fc8a9f79..edc1dcaff8713a 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -502,6 +502,7 @@ export in, intersect!, intersect, + isdisjoint, isempty, issubset, issetequal, diff --git a/test/sets.jl b/test/sets.jl index 03fa2905c7a390..6f32306e372a46 100644 --- a/test/sets.jl +++ b/test/sets.jl @@ -301,13 +301,15 @@ end @test !(Set([1,2,3]) <= Set([1,2,4])) end -@testset "issubset, symdiff" begin +@testset "issubset, symdiff, isdisjoint" begin for S in (Set, BitSet, Vector) for (l,r) in ((S([1,2]), S([3,4])), (S([5,6,7,8]), S([7,8,9])), (S([1,2]), S([3,4])), (S([5,6,7,8]), S([7,8,9])), (S([1,2,3]), S()), + (S(), S()), + (S(), S([1,2,3])), (S([1,2,3]), S([1])), (S([1,2,3]), S([1,2])), (S([1,2,3]), S([1,2,3])), @@ -317,6 +319,8 @@ end @test issubset(intersect(l,r), r) @test issubset(l, union(l,r)) @test issubset(r, union(l,r)) + @test isdisjoint(l,l) == isempty(l) + @test isdisjoint(l,r) == isempty(intersect(l,r)) if S === Vector @test sort(union(intersect(l,r),symdiff(l,r))) == sort(union(l,r)) else