Skip to content

Commit 6b051a1

Browse files
authored
Merge pull request #42 from invenia/cv/superset
Add superset function
2 parents 171b831 + b0c0b05 commit 6b051a1

File tree

3 files changed

+36
-6
lines changed

3 files changed

+36
-6
lines changed

src/Intervals.jl

+1
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,6 @@ export AbstractInterval,
4141
union!,
4242
less_than_disjoint,
4343
greater_than_disjoint,
44+
superset,
4445
.., , , , , ,
4546
end

src/interval.jl

+21-6
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,13 @@ Interval(f, l, inc...) = Interval(promote(f, l)..., inc...)
8484
Interval(interval::AbstractInterval) = convert(Interval, interval)
8585
Interval{T}(interval::AbstractInterval) where T = convert(Interval{T}, interval)
8686

87+
# Endpoint constructors
88+
function Interval{T}(left::LeftEndpoint{T}, right::RightEndpoint{T}) where T
89+
Interval{T}(left.endpoint, right.endpoint, left.included, right.included)
90+
end
91+
92+
Interval(left::LeftEndpoint{T}, right::RightEndpoint{T}) where T = Interval{T}(left, right)
93+
8794
# Empty Intervals
8895
Interval{T}() where T = Interval{T}(zero(T), zero(T), Inclusivity(false, false))
8996
Interval{T}() where T <: TimeType = Interval{T}(T(0), T(0), Inclusivity(false, false))
@@ -250,7 +257,7 @@ function Base.intersect(a::AbstractInterval{T}, b::AbstractInterval{T}) where T
250257
left = max(LeftEndpoint(a), LeftEndpoint(b))
251258
right = min(RightEndpoint(a), RightEndpoint(b))
252259

253-
return Interval{T}(left.endpoint, right.endpoint, left.included, right.included)
260+
return Interval{T}(left, right)
254261
end
255262

256263
# There is power in a union.
@@ -295,18 +302,26 @@ function Base.union!(intervals::Union{AbstractVector{<:Interval}, AbstractVector
295302
return intervals
296303
end
297304

305+
"""
306+
superset(intervals::AbstractArray{<:AbstractInterval}) -> Interval
307+
308+
Create the smallest single interval which encompasses all of the provided intervals.
309+
"""
310+
function superset(intervals::AbstractArray{<:AbstractInterval})
311+
left = minimum(LeftEndpoint.(intervals))
312+
right = maximum(RightEndpoint.(intervals))
313+
314+
return Interval(left, right)
315+
end
316+
298317
function Base.merge(a::AbstractInterval, b::AbstractInterval)
299318
if !overlaps(a, b) && !contiguous(a, b)
300319
throw(ArgumentError("$a and $b are neither overlapping or contiguous."))
301320
end
302321

303322
left = min(LeftEndpoint(a), LeftEndpoint(b))
304323
right = max(RightEndpoint(a), RightEndpoint(b))
305-
return Interval(
306-
left.endpoint,
307-
right.endpoint,
308-
Inclusivity(left.included, right.included)
309-
)
324+
return Interval(left, right)
310325
end
311326

312327
##### TIME ZONES #####

test/comparisons.jl

+14
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ const INTERVAL_TYPES = [Interval, AnchoredInterval{Ending}, AnchoredInterval{Beg
4242
@test union([earlier, later]) == [earlier, later]
4343
@test !overlaps(earlier, later)
4444
@test !contiguous(earlier, later)
45+
@test superset([earlier, later]) == Interval(1, 5, true, true)
4546
end
4647

4748
# Compare two intervals which "touch" but both intervals do not include that point:
@@ -74,6 +75,7 @@ const INTERVAL_TYPES = [Interval, AnchoredInterval{Ending}, AnchoredInterval{Beg
7475
@test union([earlier, later]) == [earlier, later]
7576
@test !overlaps(earlier, later)
7677
@test !contiguous(earlier, later)
78+
@test superset([earlier, later]) == Interval(1, 5, false, false)
7779
end
7880

7981
# Compare two intervals which "touch" and the later interval includes that point:
@@ -106,6 +108,7 @@ const INTERVAL_TYPES = [Interval, AnchoredInterval{Ending}, AnchoredInterval{Beg
106108
@test union([earlier, later]) == [Interval(1, 5, false, true)]
107109
@test !overlaps(earlier, later)
108110
@test contiguous(earlier, later)
111+
@test superset([earlier, later]) == Interval(1, 5, false, true)
109112
end
110113

111114
# Compare two intervals which "touch" and the earlier interval includes that point:
@@ -138,6 +141,7 @@ const INTERVAL_TYPES = [Interval, AnchoredInterval{Ending}, AnchoredInterval{Beg
138141
@test union([earlier, later]) == [Interval(1, 5, true, false)]
139142
@test !overlaps(earlier, later)
140143
@test contiguous(earlier, later)
144+
@test superset([earlier, later]) == Interval(1, 5, true, false)
141145
end
142146

143147
# Compare two intervals which "touch" and both intervals include that point:
@@ -170,6 +174,7 @@ const INTERVAL_TYPES = [Interval, AnchoredInterval{Ending}, AnchoredInterval{Beg
170174
@test union([earlier, later]) == [Interval(1, 5, true, true)]
171175
@test overlaps(earlier, later)
172176
@test !contiguous(earlier, later)
177+
@test superset([earlier, later]) == Interval(1, 5, true, true)
173178
end
174179

175180
# Compare two intervals which overlap
@@ -202,6 +207,7 @@ const INTERVAL_TYPES = [Interval, AnchoredInterval{Ending}, AnchoredInterval{Beg
202207
@test union([earlier, later]) == [Interval(1, 5, true, true)]
203208
@test overlaps(earlier, later)
204209
@test !contiguous(earlier, later)
210+
@test superset([earlier, later]) == Interval(1, 5, true, true)
205211
end
206212

207213
@testset "equal ()/()" begin
@@ -229,6 +235,7 @@ const INTERVAL_TYPES = [Interval, AnchoredInterval{Ending}, AnchoredInterval{Beg
229235
@test union([a, b]) == [Interval(1, 5, false, false)]
230236
@test overlaps(a, b)
231237
@test !contiguous(a, b)
238+
@test superset([a, b]) == Interval(1, 5, false, false)
232239
end
233240

234241
@testset "equal [)/()" begin
@@ -256,6 +263,7 @@ const INTERVAL_TYPES = [Interval, AnchoredInterval{Ending}, AnchoredInterval{Beg
256263
@test union([a, b]) == [Interval(1, 5, true, false)]
257264
@test overlaps(a, b)
258265
@test !contiguous(a, b)
266+
@test superset([a, b]) == Interval(1, 5, true, false)
259267
end
260268

261269
@testset "equal (]/()" begin
@@ -283,6 +291,7 @@ const INTERVAL_TYPES = [Interval, AnchoredInterval{Ending}, AnchoredInterval{Beg
283291
@test union([a, b]) == [Interval(1, 5, false, true)]
284292
@test overlaps(a, b)
285293
@test !contiguous(a, b)
294+
@test superset([a, b]) == Interval(1, 5, false, true)
286295
end
287296

288297
@testset "equal []/()" begin
@@ -310,6 +319,7 @@ const INTERVAL_TYPES = [Interval, AnchoredInterval{Ending}, AnchoredInterval{Beg
310319
@test union([a, b]) == [Interval(1, 5, true, true)]
311320
@test overlaps(a, b)
312321
@test !contiguous(a, b)
322+
@test superset([a, b]) == Interval(1, 5, true, true)
313323
end
314324

315325
@testset "equal [)/[]" begin
@@ -337,6 +347,7 @@ const INTERVAL_TYPES = [Interval, AnchoredInterval{Ending}, AnchoredInterval{Beg
337347
@test union([a, b]) == [Interval(1, 5, true, true)]
338348
@test overlaps(a, b)
339349
@test !contiguous(a, b)
350+
@test superset([a, b]) == Interval(1, 5, true, true)
340351
end
341352

342353
@testset "equal (]/[]" begin
@@ -364,6 +375,7 @@ const INTERVAL_TYPES = [Interval, AnchoredInterval{Ending}, AnchoredInterval{Beg
364375
@test union([a, b]) == [Interval(1, 5, true, true)]
365376
@test overlaps(a, b)
366377
@test !contiguous(a, b)
378+
@test superset([a, b]) == Interval(1, 5, true, true)
367379
end
368380

369381
@testset "equal []/[]" begin
@@ -391,6 +403,7 @@ const INTERVAL_TYPES = [Interval, AnchoredInterval{Ending}, AnchoredInterval{Beg
391403
@test union([a, b]) == [Interval(1, 5, true, true)]
392404
@test overlaps(a, b)
393405
@test !contiguous(a, b)
406+
@test superset([a, b]) == Interval(1, 5, true, true)
394407
end
395408

396409
# Compare two intervals where the first interval is contained by the second
@@ -423,5 +436,6 @@ const INTERVAL_TYPES = [Interval, AnchoredInterval{Ending}, AnchoredInterval{Beg
423436
@test union([smaller, larger]) == [Interval(larger)]
424437
@test overlaps(smaller, larger)
425438
@test !contiguous(smaller, larger)
439+
@test superset([smaller, larger]) == Interval(1, 5, true, true)
426440
end
427441
end

0 commit comments

Comments
 (0)