4.14 Range Sets
(require rebellion/collection/range-set) | |
package: rebellion |
A range set is a sorted collection of nonempty, disconnected ranges. All ranges in the same range set must use the same comparator. Two immutable range sets are equal? if they contain the same ranges. Two mutable range sets are equal? if they will always contain the same ranges, meaning that they share the same mutable state. This is not necessarily the same as being eq?, as some range sets may be views of others.
All range sets are sequences. When iterated, a range set traverses its ranges in ascending order as defined by the comparator shared by those ranges. To traverse a range set in descending order, use in-range-set with #:descending? set to true.
procedure
(range-set? v) → boolean?
v : any/c
procedure
(immutable-range-set? v) → boolean?
v : any/c
procedure
(mutable-range-set? v) → boolean?
v : any/c
4.14.1 Constructing Range Sets
procedure
(range-set range ... #:comparator comparator) → immutable-range-set? range : nonempty-range? comparator : comparator?
(range-set first-range range ... [ #:comparator comparator]) → immutable-range-set? first-range : nonempty-range? range : nonempty-range? comparator : comparator? = (range-comparator first-range)
> (range-set (closed-open-range 2 5)) (immutable-range-set #<range:real<=> [2, 5)>)
> (range-set (closed-open-range 4 8) (closed-open-range 0 4)) (immutable-range-set #<range:real<=> [0, 8)>)
> (range-set (greater-than-range 20) (less-than-range 5) (closed-range 10 15))
(immutable-range-set
#<range:real<=> [-∞, 5)>
#<range:real<=> [10, 15]>
#<range:real<=> (20, ∞]>)
> (range-set (closed-open-range 2 5) #:comparator real<=>) (immutable-range-set #<range:real<=> [2, 5)>)
procedure
(make-mutable-range-set [ initial-ranges] #:comparator comparator) → mutable-range-set? initial-ranges : (sequence/c range?) = '() comparator : comparator?
> (make-mutable-range-set #:comparator real<=>) (mutable-range-set
> (make-mutable-range-set (list (closed-range 2 5) (open-range 10 20)) #:comparator real<=>) (mutable-range-set #<range:real<=> [2, 5]> #<range:real<=> (10, 20)>)
procedure
(sequence->range-set ranges #:comparator comparator) → immutable-range-set? ranges : (sequence/c nonempty-range?) comparator : comparator?
> (sequence->range-set (list (closed-range 1 3) (closed-range 10 12) (closed-range 5 6)) #:comparator real<=>)
(immutable-range-set
#<range:real<=> [1, 3]>
#<range:real<=> [5, 6]>
#<range:real<=> [10, 12]>)
syntax
(for/range-set #:comparator comparator (for-clause ...) body-or-break ... body)
> (for/range-set #:comparator real<=> ([char (in-string "abcxyz")]) (define codepoint (char->integer char)) (closed-open-range codepoint (add1 codepoint))) (immutable-range-set #<range:real<=> [97, 100)> #<range:real<=> [120, 123)>)
syntax
(for*/range-set #:comparator comparator (for-clause ...) body-or-break ... body)
> (for*/range-set #:comparator real<=> ([str (in-list (list "abc" "tuv" "xyz" "qrs"))] [char (in-string str)]) (define codepoint (char->integer char)) (closed-open-range codepoint (add1 codepoint)))
(immutable-range-set
#<range:real<=> [97, 100)>
#<range:real<=> [113, 119)>
#<range:real<=> [120, 123)>)
procedure
(into-range-set comparator)
→ (reducer/c nonempty-range? immutable-range-set?) comparator : comparator?
> (transduce (list (closed-range 1 3) (closed-range 10 12) (closed-range 5 6)) #:into (into-range-set real<=>))
(immutable-range-set
#<range:real<=> [1, 3]>
#<range:real<=> [5, 6]>
#<range:real<=> [10, 12]>)
4.14.2 Iterating Range Sets
procedure
(in-range-set range-set [ #:descending? descending?]) → (sequence/c nonempty-range?) range-set : range-set? descending? : boolean? = #false
(define ranges (range-set (closed-range 1 3) (closed-range 10 12) (closed-range 5 6)))
> (for ([r (in-range-set ranges)]) (displayln r))
#<range:real<=> [1, 3]>
#<range:real<=> [5, 6]>
#<range:real<=> [10, 12]>
> (for ([r (in-range-set ranges #:descending? #true)]) (displayln r))
#<range:real<=> [10, 12]>
#<range:real<=> [5, 6]>
#<range:real<=> [1, 3]>
4.14.3 Querying Range Sets
procedure
(range-set-size ranges) → natural?
ranges : range-set?
> (range-set-size (range-set (closed-range 3 5) (closed-range 8 14))) 2
procedure
(range-set-comparator ranges) → comparator?
ranges : range-set?
procedure
(range-set-empty? ranges) → boolean?
ranges : range-set?
procedure
(range-set-contains? ranges element) → boolean?
ranges : range-set? element : any/c
(define ranges (range-set (closed-range 2 5) (closed-range 9 10)))
> (range-set-contains? ranges 2) #t
> (range-set-contains? ranges 7) #f
> (range-set-contains? ranges 10) #t
procedure
(range-set-contains-all? ranges elements) → boolean?
ranges : range-set? elements : (sequence/c any/c)
(define ranges (range-set (closed-range 2 5) (closed-range 9 10)))
> (range-set-contains-all? ranges (list 2 3 4 5 9 10)) #t
> (range-set-contains-all? ranges (list 4 7)) #f
> (range-set-contains-all? ranges (list)) #t
procedure
(range-set-encloses? ranges other-range) → boolean?
ranges : range-set? other-range : range?
(define ranges (range-set (closed-range 2 5) (closed-range 9 10)))
> (range-set-encloses? ranges (closed-range 3 4)) #t
> (range-set-encloses? ranges (closed-range 4 10)) #f
> (range-set-encloses? ranges (open-range 9 10)) #t
procedure
(range-set-encloses-all? ranges other-ranges) → boolean? ranges : range-set? other-ranges : (sequence/c range?)
> (range-set-encloses-all? (range-set (closed-range 2 5) (closed-range 7 10)) (range-set (closed-range 3 4) (closed-range 8 9))) #t
procedure
(range-set-overlaps? ranges other-range) → boolean?
ranges : range-set? other-range : range?
(define ranges (range-set (closed-range 2 5) (closed-range 9 10)))
> (range-set-overlaps? ranges (closed-range 4 8)) #t
> (range-set-overlaps? ranges (closed-range 6 8)) #f
procedure
(range-set-range-containing ranges element [ failure-result]) → any/c ranges : range-set? element : any/c failure-result : failure-result/c = (λ () (raise ...))
(define ranges (range-set (closed-range 2 5) (closed-range 9 10)))
> (range-set-range-containing ranges 4) #<range:real<=> [2, 5]>
> (range-set-range-containing ranges 9) #<range:real<=> [9, 10]>
> (range-set-range-containing ranges 7) range-set-range-containing: no range containing value;
ranges: (immutable-range-set #<range:real<=> [2, 5]>
#<range:real<=> [9, 10]>) value: 7
> (range-set-range-containing ranges 7 #false) #f
procedure
(range-set-range-containing-or-absent ranges element) → (option/c range?) ranges : range-set? element : any/c
(define ranges (range-set (closed-range 2 5) (closed-range 9 10)))
> (range-set-range-containing-or-absent ranges 4) (present #<range:real<=> [2, 5]>)
> (range-set-range-containing-or-absent ranges 9) (present #<range:real<=> [9, 10]>)
> (range-set-range-containing-or-absent ranges 7) #<absent>
procedure
(range-set-span ranges [empty-result]) → any/c
ranges : range-set? empty-result : failure-result/c = (λ () (raise ...))
> (range-set-span (range-set (closed-range 2 5) (open-range 9 10))) #<range:real<=> [2, 10)>
> (range-set-span (range-set #:comparator real<=>)) range-set-span: range set is empty and has no span
> (range-set-span (range-set #:comparator real<=>) "empty range set!") "empty range set!"
procedure
(range-set-span-or-absent ranges) → (option/c range?)
ranges : range-set?
> (range-set-span-or-absent (range-set (closed-range 2 5) (open-range 9 10))) (present #<range:real<=> [2, 10)>)
> (range-set-span-or-absent (range-set #:comparator real<=>)) #<absent>
4.14.4 Range Set Views
procedure
(range-subset ranges subset-range) → range-set?
ranges : range-set? subset-range : range?
(define ranges (range-set (closed-range 2 5) (closed-range 7 10)))
> (range-subset ranges (less-than-range 4)) (immutable-range-set #<range:real<=> [2, 4)>)
procedure
(range-set-complement ranges) → range-set?
ranges : range-set?
(define ranges (range-set (closed-range 2 5) (closed-range 7 10)))
> (range-set-complement ranges)
(immutable-range-set
#<range:real<=> [-∞, 2)>
#<range:real<=> (5, 7)>
#<range:real<=> (10, ∞]>)
4.14.5 Modifying Range Sets
procedure
(range-set-add ranges new-range) → immutable-range-set?
ranges : immutable-range-set? new-range : range?
(define ranges (range-set (closed-range 2 5) (closed-range 7 10)))
> (range-set-add ranges (closed-range 0 3)) (immutable-range-set #<range:real<=> [0, 5]> #<range:real<=> [7, 10]>)
> (range-set-add ranges (closed-range 6 12)) (immutable-range-set #<range:real<=> [2, 5]> #<range:real<=> [6, 12]>)
> (range-set-add ranges (closed-range 4 8)) (immutable-range-set #<range:real<=> [2, 10]>)
procedure
(range-set-add! ranges new-range) → void?
ranges : mutable-range-set? new-range : range?
(define ranges (make-mutable-range-set #:comparator real<=>)) (range-set-add! ranges (closed-range 2 5)) (range-set-add! ranges (closed-range 7 10))
> ranges (mutable-range-set #<range:real<=> [2, 5]> #<range:real<=> [7, 10]>)
(range-set-add! ranges (closed-range 4 8))
> ranges (mutable-range-set #<range:real<=> [2, 10]>)
procedure
(range-set-add-all ranges new-ranges) → immutable-range-set?
ranges : immutable-range-set? new-ranges : (sequence/c range?)
> (range-set-add-all (range-set (closed-range 2 5) (open-range 10 12)) (range-set (open-range 3 8) (closed-range 15 20)))
(immutable-range-set
#<range:real<=> [2, 8)>
#<range:real<=> (10, 12)>
#<range:real<=> [15, 20]>)
procedure
(range-set-add-all! ranges new-ranges) → void?
ranges : mutable-range-set? new-ranges : (sequence/c range?)
(define ranges (make-mutable-range-set #:comparator real<=>))
(range-set-add-all! ranges (list (closed-range 2 5) (open-range 10 12))) (range-set-add-all! ranges (list (open-range 3 8) (closed-range 15 20)))
> ranges
(mutable-range-set
#<range:real<=> [2, 8)>
#<range:real<=> (10, 12)>
#<range:real<=> [15, 20]>)
procedure
(range-set-remove ranges range-to-remove) → immutable-range-set?
ranges : immutable-range-set? range-to-remove : range?
> (range-set-remove (range-set (closed-range 1 5) (closed-range 8 10)) (closed-range 3 12)) (immutable-range-set #<range:real<=> [1, 3)>)
procedure
(range-set-remove! ranges range-to-remove) → void?
ranges : mutable-range-set? range-to-remove : range?
(define ranges (make-mutable-range-set #:comparator real<=>)) (range-set-add-all! ranges (list (closed-range 1 5) (closed-range 8 10)))
> ranges (mutable-range-set #<range:real<=> [1, 5]> #<range:real<=> [8, 10]>)
(range-set-remove! ranges (closed-range 3 12))
> ranges (mutable-range-set #<range:real<=> [1, 3)>)
procedure
(range-set-remove-all ranges ranges-to-remove) → immutable-range-set? ranges : immutable-range-set? ranges-to-remove : (sequence/c range?)
> (range-set-remove-all (range-set (closed-range 1 5) (closed-range 8 10)) (range-set (open-range 3 7) (closed-range 9 15))) (immutable-range-set #<range:real<=> [1, 3]> #<range:real<=> [8, 9)>)
procedure
(range-set-remove-all! ranges ranges-to-remove) → void? ranges : mutable-range-set? ranges-to-remove : (sequence/c range?)
(define ranges (make-mutable-range-set #:comparator real<=>)) (range-set-add-all! ranges (list (closed-range 1 5) (closed-range 8 10)))
> ranges (mutable-range-set #<range:real<=> [1, 5]> #<range:real<=> [8, 10]>)
(range-set-remove-all! ranges (list (open-range 3 7) (closed-range 9 15)))
> ranges (mutable-range-set #<range:real<=> [1, 3]> #<range:real<=> [8, 9)>)
procedure
(range-set-clear! ranges) → void?
ranges : mutable-range-set?