range-ts
Version:
RangeMap implementation based on Guava
149 lines • 6.22 kB
JavaScript
import { __read, __spreadArray } from "tslib";
import { NumberRange } from "../number-range/number-range";
import { BoundType } from "../core/bound-type";
var RangeMap = (function () {
function RangeMap(eq) {
if (eq === void 0) { eq = function (a, b) { return a === b; }; }
this.eq = eq;
this.rangeValues = [];
}
RangeMap.fromRangeValues = function (values, eq) {
var rangeMap = new RangeMap(eq);
rangeMap.rangeValues = values;
return rangeMap;
};
RangeMap.prototype.put = function (range, value) {
this.combinedPut(range, value, false);
};
RangeMap.prototype.putCoalescing = function (range, value) {
this.combinedPut(range, value, true);
};
RangeMap.prototype.get = function (value) {
var foundRangeValue = this.rangeValues.find(function (currentRangeValue) {
return currentRangeValue.range.contains(value);
});
if (foundRangeValue) {
return foundRangeValue.value;
}
return null;
};
RangeMap.prototype.asMapOfRanges = function () {
var newMap = new Map();
this.rangeValues
.filter(function (range) { return !range.range.isEmpty(); })
.sort(function (a, b) {
return a.range.lowerEndpoint.valueOf() - b.range.lowerEndpoint.valueOf();
})
.forEach(function (currentRangeValue) {
newMap.set(currentRangeValue.range, currentRangeValue.value);
});
return newMap;
};
RangeMap.prototype.asMapOfValues = function () {
var newMap = new Map();
this.rangeValues
.filter(function (range) { return !range.range.isEmpty(); })
.sort(function (a, b) {
return a.range.lowerEndpoint.valueOf() - b.range.lowerEndpoint.valueOf();
})
.forEach(function (currentRangeValue) {
if (newMap.has(currentRangeValue.value)) {
newMap.get(currentRangeValue.value).push(currentRangeValue.range);
}
else {
newMap.set(currentRangeValue.value, [currentRangeValue.range]);
}
});
return newMap;
};
RangeMap.prototype.subRangeMap = function (range) {
var rangeValues = this.rangeValues.flatMap(function (rangeValue) {
var intersection = rangeValue.range.intersection(range);
if (!intersection) {
return [];
}
return [
{
range: intersection,
value: rangeValue.value,
},
];
});
return RangeMap.fromRangeValues(rangeValues);
};
RangeMap.prototype.getEntry = function (key) {
var foundRangeValue = this.rangeValues.find(function (currentRangeValue) {
return currentRangeValue.range.contains(key);
});
if (foundRangeValue) {
return [foundRangeValue.range, foundRangeValue.value];
}
return null;
};
RangeMap.prototype.span = function () {
if (this.rangeValues.length === 0) {
return null;
}
var sortedRangeValues = this.rangeValues.sort(function (a, b) {
return a.range.lowerEndpoint.valueOf() - b.range.lowerEndpoint.valueOf();
});
return new NumberRange(sortedRangeValues[0].range.lowerEndpoint, sortedRangeValues[0].range.lowerBoundType, sortedRangeValues[sortedRangeValues.length - 1].range.upperEndpoint, sortedRangeValues[sortedRangeValues.length - 1].range.upperBoundType);
};
RangeMap.prototype.remove = function (range) {
if (range.isEmpty()) {
return;
}
var toDelete = {
toDeleteId: Math.random()
};
this.put(range, toDelete);
this.rangeValues = this.rangeValues.filter(function (rangeValue) { return rangeValue.value !== toDelete; });
};
RangeMap.prototype.combinedPut = function (range, value, shouldPutCoalescing) {
var _this = this;
if (shouldPutCoalescing === void 0) { shouldPutCoalescing = false; }
var newRange = range;
var affectedRangeValues = [];
var unaffectedRangeValues = [];
this.rangeValues.forEach(function (currentRangeValue) {
if (currentRangeValue.range.isConnected(newRange)) {
affectedRangeValues.push(currentRangeValue);
}
else {
unaffectedRangeValues.push(currentRangeValue);
}
});
affectedRangeValues = affectedRangeValues.flatMap(function (currentRangeValue) {
var _a;
if (shouldPutCoalescing && _this.eq(value, currentRangeValue.value)) {
newRange = newRange.span(currentRangeValue.range);
return [];
}
if ((_a = currentRangeValue.range.intersection(newRange)) === null || _a === void 0 ? void 0 : _a.isEmpty()) {
return [currentRangeValue];
}
var rangeBefore = currentRangeValue.range.intersection(NumberRange.upTo(newRange.lowerEndpoint, newRange.lowerBoundType === BoundType.OPEN
? BoundType.CLOSED
: BoundType.OPEN));
var rangeAfter = currentRangeValue.range.intersection(new NumberRange(newRange.upperEndpoint, newRange.upperBoundType === BoundType.OPEN
? BoundType.CLOSED
: BoundType.OPEN, Number.POSITIVE_INFINITY, BoundType.OPEN));
return [rangeBefore, rangeAfter]
.filter(function (a) { return !!a; })
.filter(function (a) { return !a.isEmpty(); })
.map(function (currentRange) { return ({
range: currentRange,
value: currentRangeValue.value,
}); });
});
this.rangeValues = __spreadArray(__spreadArray(__spreadArray([], __read(unaffectedRangeValues), false), __read(affectedRangeValues), false), [
{
range: newRange,
value: value,
},
], false);
};
return RangeMap;
}());
export { RangeMap };
//# sourceMappingURL=range-map.js.map