@@ -85,32 +85,33 @@ const prepareInput = (typeStr: string, i: interval | roai): IntervalSE[] => {
85
85
86
86
const complementGen = ( boundaries : IntervalSE , intervals : IntervalSE [ ] ) : IntervalSE [ ] => {
87
87
const intervalsS = sortByStart ( intervals ) ;
88
+ const { start, end, ...rest } = boundaries ;
88
89
const prepRanges : IntervalSE [ ] = [
89
- { start : - Infinity , end : boundaries . start } ,
90
+ { start : - Infinity , end : start } ,
90
91
...intervalsS ,
91
- { start : boundaries . end , end : Infinity } ,
92
+ { start : end , end : Infinity } ,
92
93
] ;
93
94
return reject < IntervalSE | null > (
94
95
isNil ,
95
96
aperture ( 2 , prepRanges ) . map (
96
- ( [ r1 , r2 ] ) => ( r1 . end >= r2 . start ? null : { start : r1 . end , end : r2 . start } )
97
+ ( [ r1 , r2 ] ) => ( r1 . end >= r2 . start ? null : { start : r1 . end , end : r2 . start , ... rest } )
97
98
)
98
99
) as IntervalSE [ ] ;
99
100
} ;
100
101
101
- const complementCurry = < T extends interval > ( boundaries : interval , intervals : T | T [ ] ) : T [ ] => {
102
+ const complementCurry = < D extends interval , T extends interval > ( boundaries : D , intervals : T | T [ ] ) : D [ ] => {
102
103
if ( Array . isArray ( intervals ) && intervals . length < 1 ) {
103
- return [ boundaries ] as T [ ] ;
104
+ return [ boundaries ] as D [ ] ;
104
105
}
105
- const typeStr = getType ( intervals ) ;
106
+ const typeStr = getType ( boundaries ) ;
106
107
const intervalSE = prepareInput ( typeStr , intervals ) ;
107
108
const boundariesSE = convertFrom ( getType ( boundaries ) ) ( boundaries ) ;
108
- return complementGen ( boundariesSE , intervalSE ) . map ( convertTo < T > ( typeStr ) ) ;
109
+ return complementGen ( boundariesSE , intervalSE ) . map ( convertTo < D > ( typeStr ) ) ;
109
110
} ;
110
111
111
112
/**
112
113
* Complement of `intervals` bounded to `boundaries`. Convert space between two consecutive intervals into interval.
113
- *
114
+ * Keeps extra object properties on `boundaries`.
114
115
* Curried function. Accept array of intervals. Doesn't mutate input. Output keeps input's structure.
115
116
*
116
117
* boundaries | interval(s) | result
@@ -122,16 +123,16 @@ const complementCurry = <T extends interval>(boundaries: interval, intervals: T
122
123
* @param intervals arg2: one interval or array of intervals that complement the result.
123
124
* @returns array of intervals.
124
125
*/
125
- export function complement < T extends interval > ( boundaries : interval , interv : T | roat < T > ) : T [ ] ;
126
- export function complement < T extends interval > ( boundaries : interval ) : ( interv : T | roat < T > ) => T [ ] ;
127
- export function complement < T extends interval > ( boundaries : interval , interv ?: T | roat < T > ) : any {
126
+ export function complement < D extends interval , T extends interval > ( boundaries : D , interv : T | roat < T > ) : D [ ] ;
127
+ export function complement < D extends interval , T extends interval > ( boundaries : D ) : ( interv : T | roat < T > ) => D [ ] ;
128
+ export function complement < D extends interval , T extends interval > ( boundaries : D , interv ?: T | roat < T > ) : any {
128
129
switch ( arguments . length ) {
129
130
case 1 :
130
- return ( tt2 : T | T [ ] ) : T [ ] => {
131
- return complementCurry < T > ( boundaries , tt2 ) ;
131
+ return ( tt2 : T | T [ ] ) : D [ ] => {
132
+ return complementCurry < D , T > ( boundaries , tt2 ) ;
132
133
} ;
133
134
case 2 :
134
- return complementCurry < T > ( boundaries , interv as T | T [ ] ) ;
135
+ return complementCurry < D , T > ( boundaries , interv as T | T [ ] ) ;
135
136
}
136
137
}
137
138
@@ -634,14 +635,15 @@ const subtractInter = (mask: IntervalSE[], base: IntervalSE): IntervalSE[] => {
634
635
} ;
635
636
636
637
const substractGen = ( base : IntervalSE [ ] , mask : IntervalSE [ ] ) : IntervalSE [ ] => {
637
- const intersection = intersectGen ( base , mask ) ;
638
+ const intersection = intersectGen ( mask , base ) ;
638
639
return unnest (
639
640
base . map ( b => subtractInter ( intersection . filter ( isOverlappingSimple . bind ( null , b ) ) , b ) )
640
641
) ;
641
642
} ;
642
643
643
644
/**
644
645
* Subtact `intervalA` with `intervalB`. `intervalB` act as a mask.
646
+ * Keeps extra object properties on `intervalA`.
645
647
*
646
648
* Curried function. Accept array of intervals. Doesn't mutate input. Output keeps input's structure.
647
649
*
@@ -654,20 +656,20 @@ const substractGen = (base: IntervalSE[], mask: IntervalSE[]): IntervalSE[] => {
654
656
* @param intervalB arg2: one interval or array of intervals
655
657
* @returns intersection of `arg1` and `arg2`
656
658
*/
657
- export function substract < T extends interval > ( intervalA : T | roat < T > , intervalB : T | roat < T > ) : T [ ] ;
658
- export function substract < T extends interval > (
659
- intervalA : T | roat < T >
660
- ) : ( intervalB : T | roat < T > ) => T [ ] ;
661
- export function substract < T extends interval > (
662
- intervalA : T | roat < T > ,
659
+ export function substract < D extends interval , T extends interval > ( intervalA : D | roat < D > , intervalB : T | roat < T > ) : D [ ] ;
660
+ export function substract < D extends interval , T extends interval > (
661
+ intervalA : D | roat < D >
662
+ ) : ( intervalB : T | roat < T > ) => D [ ] ;
663
+ export function substract < D extends interval , T extends interval > (
664
+ intervalA : D | roat < D > ,
663
665
intervalB ?: T | roat < T >
664
666
) : any {
665
667
switch ( arguments . length ) {
666
668
case 1 :
667
- return ( tt2 : T | T [ ] ) : T [ ] => {
668
- return setupForTwoIntsToInts < T > ( substractGen ) ( intervalA , tt2 ) ;
669
+ return ( tt2 : T | T [ ] ) : D [ ] => {
670
+ return setupForTwoIntsToInts < D > ( substractGen ) ( intervalA , tt2 as any ) ;
669
671
} ;
670
672
case 2 :
671
- return setupForTwoIntsToInts < T > ( substractGen ) ( intervalA , intervalB as T | T [ ] ) ;
673
+ return setupForTwoIntsToInts < D > ( substractGen ) ( intervalA , intervalB as any ) ;
672
674
}
673
675
}
0 commit comments