UNPKG

range-ts

Version:

RangeMap implementation based on Guava

171 lines 7.15 kB
import { BoundType } from "../core/bound-type"; export class NumberRange { constructor(lowerEndpoint, lowerBoundType, upperEndpoint, upperBoundType) { this.lowerEndpoint = lowerEndpoint; this.lowerBoundType = lowerBoundType; this.upperEndpoint = upperEndpoint; this.upperBoundType = upperBoundType; } get lowerEndpointValue() { var _a; return (_a = this.lowerEndpoint) === null || _a === void 0 ? void 0 : _a.valueOf(); } get upperEndpointValue() { var _a; return (_a = this.upperEndpoint) === null || _a === void 0 ? void 0 : _a.valueOf(); } static closedOpen(lower, upper) { return new NumberRange(lower, BoundType.CLOSED, upper, BoundType.OPEN); } static closed(lower, upper) { return new NumberRange(lower, BoundType.CLOSED, upper, BoundType.CLOSED); } static open(lower, upper) { return new NumberRange(lower, BoundType.OPEN, upper, BoundType.OPEN); } static openClosed(lower, upper) { return new NumberRange(lower, BoundType.OPEN, upper, BoundType.CLOSED); } static all() { return new NumberRange(Number.NEGATIVE_INFINITY, BoundType.OPEN, Number.POSITIVE_INFINITY, BoundType.OPEN); } static atLeast(endpoint) { return new NumberRange(endpoint, BoundType.CLOSED, Number.POSITIVE_INFINITY, BoundType.OPEN); } static atMost(endpoint) { return new NumberRange(Number.NEGATIVE_INFINITY, BoundType.OPEN, endpoint, BoundType.CLOSED); } static downTo(endpoint, boundType) { return new NumberRange(endpoint, boundType, Number.POSITIVE_INFINITY, BoundType.OPEN); } static upTo(endpoint, boundType) { return new NumberRange(Number.NEGATIVE_INFINITY, BoundType.OPEN, endpoint, boundType); } contains(comparable) { const value = comparable === null || comparable === void 0 ? void 0 : comparable.valueOf(); const aboveLowerEndpoint = this.lowerBoundType === BoundType.OPEN ? this.lowerEndpointValue < value : this.lowerEndpointValue <= value; const belowUpperEndpoint = this.upperBoundType === BoundType.OPEN ? this.upperEndpointValue > value : this.upperEndpointValue >= value; return aboveLowerEndpoint && belowUpperEndpoint; } encloses(other) { const lowerEndpointEnclosed = other.lowerBoundType === BoundType.OPEN ? this.contains(other.lowerEndpoint) || this.lowerEndpointValue === other.lowerEndpointValue : this.contains(other.lowerEndpoint); const upperEndpointEnclosed = other.upperBoundType === BoundType.OPEN ? this.contains(other.upperEndpoint) || this.upperEndpointValue === other.upperEndpointValue : this.contains(other.upperEndpoint); return lowerEndpointEnclosed && upperEndpointEnclosed; } overlaps(other) { var _a; const intersection = this.intersection(other); return (_a = (intersection && !intersection.isEmpty())) !== null && _a !== void 0 ? _a : false; } intersection(other) { if (!this.isConnected(other)) { return null; } const lowerRange = this.lowerEndpointValue <= other.lowerEndpointValue ? other : this; const upperRange = this.upperEndpointValue >= other.upperEndpointValue ? other : this; let lowerBoundType; let upperBoundType; if (this.lowerEndpointValue === other.lowerEndpointValue) { lowerBoundType = this.lowerBoundType === BoundType.OPEN || other.lowerBoundType === BoundType.OPEN ? BoundType.OPEN : BoundType.CLOSED; } else { lowerBoundType = lowerRange.lowerBoundType; } if (this.upperEndpointValue === other.upperEndpointValue) { upperBoundType = this.upperBoundType === BoundType.OPEN || other.upperBoundType === BoundType.OPEN ? BoundType.OPEN : BoundType.CLOSED; } else { upperBoundType = upperRange.upperBoundType; } return new NumberRange(lowerRange.lowerEndpoint, lowerBoundType, upperRange.upperEndpoint, upperBoundType); } isConnected(other) { return (this.contains(other.lowerEndpoint) || this.contains(other.upperEndpoint) || other.contains(this.lowerEndpoint) || other.contains(this.upperEndpoint)); } isEmpty() { return (this.lowerEndpointValue === this.upperEndpointValue && (this.lowerBoundType === BoundType.OPEN || this.upperBoundType === BoundType.OPEN)); } span(other) { const lowerRange = this.lowerEndpointValue <= other.lowerEndpointValue ? this : other; const upperRange = this.upperEndpointValue >= other.upperEndpointValue ? this : other; let lowerBoundType; let upperBoundType; if (this.lowerEndpointValue === other.lowerEndpointValue) { lowerBoundType = this.lowerBoundType === BoundType.CLOSED || other.lowerBoundType === BoundType.CLOSED ? BoundType.CLOSED : BoundType.OPEN; } else { lowerBoundType = lowerRange.lowerBoundType; } if (this.upperEndpointValue === other.upperEndpointValue) { upperBoundType = this.upperBoundType === BoundType.CLOSED || other.upperBoundType === BoundType.CLOSED ? BoundType.CLOSED : BoundType.OPEN; } else { upperBoundType = upperRange.upperBoundType; } return new NumberRange(lowerRange.lowerEndpoint, lowerBoundType, upperRange.upperEndpoint, upperBoundType); } toString() { const getLowerBoundCharacter = () => { switch (this.lowerBoundType) { case BoundType.OPEN: return "("; case BoundType.CLOSED: return "["; } }; const getUpperBoundCharacter = () => { switch (this.upperBoundType) { case BoundType.OPEN: return ")"; case BoundType.CLOSED: return "]"; } }; const valueToString = (value) => { switch (value.valueOf()) { case Number.POSITIVE_INFINITY: return "+∞"; case Number.NEGATIVE_INFINITY: return "-∞"; default: if (value['toISOString']) { return value.toISOString(); } return value.valueOf(); } }; return `${getLowerBoundCharacter()}${valueToString(this.lowerEndpoint)}..${valueToString(this.upperEndpoint)}${getUpperBoundCharacter()}`; } } //# sourceMappingURL=number-range.js.map