UNPKG

covutils

Version:

Utilities for creating, transforming, and handling Coverage Data objects.

115 lines (112 loc) 3.1 kB
'use strict'; 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; } }