covutils
Version:
Utilities for creating, transforming, and handling Coverage Data objects.
115 lines (112 loc) • 3.1 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.minMax = minMax;
exports.indicesOfNearest = indicesOfNearest;
exports.indexOfNearest = indexOfNearest;
function minMax(arr) {
var len = arr.length;
var min = Infinity;
var max = -Infinity;
while (len--) {
var el = arr[len];
if (el == null) {
// do nothing
} else if (el < min) {
min = el;
} else if (el > max) {
max = el;
}
}
if (min === Infinity) {
min = max;
} else if (max === -Infinity) {
max = min;
}
if (min === Infinity || min === -Infinity) {
// all values were null
min = null;
max = null;
}
return [min, max];
}
/**
* Return the indices of the two neighbors in the sorted array closest to the given number.
*
* @example
* var a = [2,5,8,12,13]
* var i = CovUtils.indicesOfNearest(a, 6)
* // i == [1,2]
* var j = CovUtils.indicesOfNearest(a, 5)
* // j == [1,1]
* var k = CovUtils.indicesOfNearest(a, 50)
* // k == [4,4]
*
* @param {Array<number>} a The array to search through. Must be sorted, ascending or descending.
* @param {number} x The target number.
* @return {[lo,hi]} The indices of the two closest values, may be equal.
* If `x` exists in the array, both neighbors point to `x`.
* If `x` is lower (greater if descending) than the first value, both neighbors point to 0.
* If `x` is greater (lower if descending) than the last value, both neighbors point to the last index.
*/
function indicesOfNearest(a, x) {
if (a.length === 0) {
throw new Error('Array must have at least one element');
}
var lo = -1;
var hi = a.length;
var ascending = a.length === 1 || a[0] < a[1];
// we have two separate code paths to help the runtime optimize the loop
if (ascending) {
while (hi - lo > 1) {
var mid = Math.round((lo + hi) / 2);
if (a[mid] <= x) {
lo = mid;
} else {
hi = mid;
}
}
} else {
while (hi - lo > 1) {
var _mid = Math.round((lo + hi) / 2);
if (a[_mid] >= x) {
// here's the difference
lo = _mid;
} else {
hi = _mid;
}
}
}
if (a[lo] === x) hi = lo;
if (lo === -1) lo = hi;
if (hi === a.length) hi = lo;
return [lo, hi];
}
/**
* Return the index of the value closest to the given number in a sorted array.
*
* @example
* var a = [2,5,8,12,13]
* var i = CovUtils.indexOfNearest(a, 6)
* // i == 1
* var j = CovUtils.indexOfNearest(a, 7)
* // j == 2
* var k = CovUtils.indexOfNearest(a, 50)
* // k == 4
*
* @param {Array<number>} a The array to search through. Must be sorted, ascending or descending.
* @param {number} x The target number.
* @return {number} The array index whose value is closest to `x`.
* If `x` happens to be exactly between two values, then the lower index is returned.
*/
function indexOfNearest(a, x) {
var i = indicesOfNearest(a, x);
var lo = i[0];
var hi = i[1];
if (Math.abs(x - a[lo]) <= Math.abs(x - a[hi])) {
return lo;
} else {
return hi;
}
}