closed-interval
Version:
Utilities for working with a range of items of any type
117 lines (116 loc) • 3.58 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const makeComparator = () => (v1, v2) => {
if (v1 < v2) {
return -1;
}
else if (v1 > v2) {
return 1;
}
else {
return 0;
}
};
class Range {
constructor(fromInclusive, toInclusive, customComparator = null) {
this.customComparator = customComparator;
this.comparator =
customComparator === null ? makeComparator() : customComparator;
if (this.comparator(fromInclusive, toInclusive) === -1) {
this.minimum = fromInclusive;
this.maximum = toInclusive;
}
else {
this.minimum = toInclusive;
this.maximum = fromInclusive;
}
}
/**
* @deprecated Use Range.of instead.
*/
static between(fromInclusive, toInclusive, comparator = null) {
return Range.of(fromInclusive, toInclusive, comparator);
}
static of(fromInclusive, toInclusive, comparator = null) {
return new Range(fromInclusive, toInclusive, comparator);
}
static is(element, comparator = null) {
return Range.between(element, element, comparator);
}
contains(element) {
return (this.comparator(this.minimum, element) <= 0 &&
this.comparator(this.maximum, element) >= 0);
}
containsRange(other) {
return (this.contains(other.getMinimum()) && this.contains(other.getMaximum()));
}
elementCompareTo(element) {
if (this.comparator(this.minimum, element) === 1) {
return -1;
}
if (this.comparator(this.maximum, element) === -1) {
return 1;
}
return 0;
}
fit(element) {
if (this.elementCompareTo(element) === -1) {
return this.minimum;
}
if (this.elementCompareTo(element) === 1) {
return this.maximum;
}
return element;
}
getComparator() {
return this.comparator;
}
getMaximum() {
return this.maximum;
}
getMinimum() {
return this.minimum;
}
intersectionWith(other) {
if (!this.isOverlappedBy(other)) {
throw new Error(`Cannot calculate intersection with non-overlapping range ${other}`);
}
const min = this.getComparator()(this.minimum, other.getMinimum()) < 0
? other.getMinimum()
: this.minimum;
const max = this.getComparator()(this.maximum, other.getMaximum()) < 0
? this.maximum
: other.getMaximum();
return Range.between(min, max, this.getComparator());
}
isAfter(element) {
return this.comparator(element, this.minimum) < 0;
}
isAfterRange(otherRange) {
return this.isAfter(otherRange.getMaximum());
}
isBefore(element) {
return this.comparator(element, this.maximum) > 0;
}
isBeforeRange(otherRange) {
return this.isBefore(otherRange.getMinimum());
}
isEndedBy(element) {
return this.comparator(element, this.maximum) === 0;
}
isNaturalOrdering() {
return this.customComparator === null;
}
isOverlappedBy(otherRange) {
return (otherRange.contains(this.minimum) ||
otherRange.contains(this.maximum) ||
this.contains(otherRange.getMinimum()));
}
isStartedBy(element) {
return this.comparator(element, this.minimum) === 0;
}
toString() {
return `[${this.minimum}..${this.maximum}]`;
}
}
exports.default = Range;