Skip to content

Commit bc0e5d1

Browse files
authored
Add isdisjoint (#34427)
This was added in #13192, but the PR became stale. We've also changed a bit how we write these kinds of algorithms, so make use of the tools we have (e.g. `fastin`).
1 parent f68753c commit bc0e5d1

File tree

3 files changed

+33
-2
lines changed

3 files changed

+33
-2
lines changed

base/abstractset.jl

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,8 @@ true
260260
"""
261261
issubset, ,
262262

263+
const FASTIN_SET_THRESHOLD = 70
264+
263265
function issubset(l, r)
264266
if haslength(r) && (isa(l, AbstractSet) || !hasfastin(r))
265267
rlen = length(r) # conditions above make this length computed only when needed
@@ -269,7 +271,7 @@ function issubset(l, r)
269271
end
270272
# when `in` would be too slow and r is big enough, convert it to a Set
271273
# this threshold was empirically determined (cf. #26198)
272-
if !hasfastin(r) && rlen > 70
274+
if !hasfastin(r) && rlen > FASTIN_SET_THRESHOLD
273275
return issubset(l, Set(r))
274276
end
275277
end
@@ -375,6 +377,30 @@ function issetequal(l, r)
375377
return issetequal(Set(l), Set(r))
376378
end
377379

380+
## set disjoint comparison
381+
"""
382+
isdisjoint(v1, v2) -> Bool
383+
384+
Returns whether the collections `v1` and `v2` are disjoint, i.e. whether
385+
their intersection is empty.
386+
387+
!!! compat "Julia 1.5"
388+
This function requires at least Julia 1.5.
389+
"""
390+
function isdisjoint(l, r)
391+
function _isdisjoint(l, r)
392+
hasfastin(r) && return !any(in(r), l)
393+
hasfastin(l) && return !any(in(l), r)
394+
haslength(r) && length(r) < FASTIN_SET_THRESHOLD &&
395+
return !any(in(r), l)
396+
return !any(in(Set(r)), l)
397+
end
398+
if haslength(l) && haslength(r) && length(r) < length(l)
399+
return _isdisjoint(r, l)
400+
end
401+
_isdisjoint(l, r)
402+
end
403+
378404
## partial ordering of sets by containment
379405

380406
==(l::AbstractSet, r::AbstractSet) = length(l) == length(r) && l r

base/exports.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,7 @@ export
502502
in,
503503
intersect!,
504504
intersect,
505+
isdisjoint,
505506
isempty,
506507
issubset,
507508
issetequal,

test/sets.jl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,13 +301,15 @@ end
301301
@test !(Set([1,2,3]) <= Set([1,2,4]))
302302
end
303303

304-
@testset "issubset, symdiff" begin
304+
@testset "issubset, symdiff, isdisjoint" begin
305305
for S in (Set, BitSet, Vector)
306306
for (l,r) in ((S([1,2]), S([3,4])),
307307
(S([5,6,7,8]), S([7,8,9])),
308308
(S([1,2]), S([3,4])),
309309
(S([5,6,7,8]), S([7,8,9])),
310310
(S([1,2,3]), S()),
311+
(S(), S()),
312+
(S(), S([1,2,3])),
311313
(S([1,2,3]), S([1])),
312314
(S([1,2,3]), S([1,2])),
313315
(S([1,2,3]), S([1,2,3])),
@@ -317,6 +319,8 @@ end
317319
@test issubset(intersect(l,r), r)
318320
@test issubset(l, union(l,r))
319321
@test issubset(r, union(l,r))
322+
@test isdisjoint(l,l) == isempty(l)
323+
@test isdisjoint(l,r) == isempty(intersect(l,r))
320324
if S === Vector
321325
@test sort(union(intersect(l,r),symdiff(l,r))) == sort(union(l,r))
322326
else

0 commit comments

Comments
 (0)