UNPKG

@jcoreio/precise-bs

Version:

binary search and related utility functions

312 lines (301 loc) 14.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DEFAULT_COMPARATOR = void 0; exports.binarySearch = binarySearch; exports.ceilingEntry = ceilingEntry; exports.ceilingIndex = void 0; exports.ceilingValue = ceilingValue; exports.floorEntry = floorEntry; exports.floorIndex = floorIndex; exports.floorValue = floorValue; exports.higherEntry = higherEntry; exports.higherIndex = higherIndex; exports.higherValue = higherValue; exports.lowerEntry = lowerEntry; exports.lowerIndex = lowerIndex; exports.lowerValue = lowerValue; // eslint-disable-next-line @typescript-eslint/no-explicit-any var DEFAULT_COMPARATOR = function DEFAULT_COMPARATOR(a, b) { return a < b ? -1 : a > b ? 1 : 0; }; exports.DEFAULT_COMPARATOR = DEFAULT_COMPARATOR; function binarySearch(array, find) { var comparator = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : DEFAULT_COMPARATOR; var low = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0; var high = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : array.length - 1; var i, comparison; while (low <= high) { i = Math.floor((low + high) / 2); comparison = comparator(array[i], find); if (comparison < 0) { low = i + 1; continue; } if (comparison > 0) { high = i - 1; continue; } return i; } return low; } /** * Finds the index of the greatest element less than a given search value in a sorted array * using a binary search. If the given search value is less than or equal to all elements in the * array, returns -1. * * @param {array} the array to search in. * @param {find} the value to search for. * @param {comparator} two-argument function that returns &lt; 0 if * the first argument is less than the second; &gt; 0 if the first * argument is greater; and 0 otherwise. (defaults to <code>a - b</code>) * @param {low} the lower bound of the range in <code>array</code> to * search in (defaults to 0) * @param {high} the upper bound of the range in <code>array</code> to * search in (defaults to <code>array.length - 1</code>) */ function lowerIndex(array, find) { var comparator = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : DEFAULT_COMPARATOR; var low = arguments.length > 3 ? arguments[3] : undefined; var high = arguments.length > 4 ? arguments[4] : undefined; return binarySearch(array, find, comparator, low, high) - 1; } /** * Finds the entry with the greatest element less than a given search value in a sorted array * using a binary search. If the search value is less than or equal to all elements in the * array, returns [-1, undefined]. * * @param {array} the array to search in. * @param {find} the value to search for. * @param {comparator} two-argument function that returns &lt; 0 if * the first argument is less than the second; &gt; 0 if the first * argument is greater; and 0 otherwise. (defaults to <code>a - b</code>) * @param {low} the lower bound of the range in <code>array</code> to * search in (defaults to 0) * @param {high} the upper bound of the range in <code>array</code> to * search in (defaults to <code>array.length - 1</code>) */ function lowerEntry(array, find) { var comparator = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : DEFAULT_COMPARATOR; var low = arguments.length > 3 ? arguments[3] : undefined; var high = arguments.length > 4 ? arguments[4] : undefined; var index = lowerIndex(array, find, comparator, low, high); return [index, array[index]]; } /** * Finds the greatest element less than a given value in a sorted array * using a binary search. If the given value is less than or equal to all elements in the * array, returns undefined. * * @param {array} the array to search in. * @param {find} the value to search for. * @param {comparator} two-argument function that returns &lt; 0 if * the first argument is less than the second; &gt; 0 if the first * argument is greater; and 0 otherwise. (defaults to <code>a - b</code>) * @param {low} the lower bound of the range in <code>array</code> to * search in (defaults to 0) * @param {high} the upper bound of the range in <code>array</code> to * search in (defaults to <code>array.length - 1</code>) */ function lowerValue(array, find) { var comparator = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : DEFAULT_COMPARATOR; var low = arguments.length > 3 ? arguments[3] : undefined; var high = arguments.length > 4 ? arguments[4] : undefined; var index = lowerIndex(array, find, comparator, low, high); return array[index]; } /** * Finds the index of the greatest element less than or equal to a given search value in a sorted array * using a binary search. If the given value is less than all elements in the * array, returns -1. * * @param {array} the array to search in. * @param {find} the value to search for. * @param {comparator} two-argument function that returns &lt; 0 if * the first argument is less than the second; &gt; 0 if the first * argument is greater; and 0 otherwise. (defaults to <code>a - b</code>) * @param {low} the lower bound of the range in <code>array</code> to * search in (defaults to 0) * @param {high} the upper bound of the range in <code>array</code> to * search in (defaults to <code>array.length - 1</code>) */ function floorIndex(array, find) { var comparator = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : DEFAULT_COMPARATOR; var low = arguments.length > 3 ? arguments[3] : undefined; var high = arguments.length > 4 ? arguments[4] : undefined; var i = binarySearch(array, find, comparator, low, high); return i === array.length || comparator(array[i], find) > 0 ? i - 1 : i; } /** * Finds the entry with the greatest element less than or equal to a given search value in a sorted array * using a binary search. If the given value is less than all elements in the * array, returns [-1, undefined]. * * @param {array} the array to search in. * @param {find} the value to search for. * @param {comparator} two-argument function that returns &lt; 0 if * the first argument is less than the second; &gt; 0 if the first * argument is greater; and 0 otherwise. (defaults to <code>a - b</code>) * @param {low} the lower bound of the range in <code>array</code> to * search in (defaults to 0) * @param {high} the upper bound of the range in <code>array</code> to * search in (defaults to <code>array.length - 1</code>) */ function floorEntry(array, find) { var comparator = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : DEFAULT_COMPARATOR; var low = arguments.length > 3 ? arguments[3] : undefined; var high = arguments.length > 4 ? arguments[4] : undefined; var index = floorIndex(array, find, comparator, low, high); return [index, array[index]]; } /** * Finds the greatest element less than or equal to a given search value in a sorted array * using a binary search. If the given value is less than all elements in the * array, returns undefined. * * @param {array} the array to search in. * @param {find} the value to search for. * @param {comparator} two-argument function that returns &lt; 0 if * the first argument is less than the second; &gt; 0 if the first * argument is greater; and 0 otherwise. (defaults to <code>a - b</code>) * @param {low} the lower bound of the range in <code>array</code> to * search in (defaults to 0) * @param {high} the upper bound of the range in <code>array</code> to * search in (defaults to <code>array.length - 1</code>) */ function floorValue(array, find) { var comparator = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : DEFAULT_COMPARATOR; var low = arguments.length > 3 ? arguments[3] : undefined; var high = arguments.length > 4 ? arguments[4] : undefined; var index = floorIndex(array, find, comparator, low, high); return array[index]; } /** * Finds the index of the least element greater than or equal to a given search value in a sorted array * using a binary search. If the given value is greater than all elements in the * array, returns the length of the array. * * @param {array} the array to search in. * @param {find} the value to search for. * @param {comparator} two-argument function that returns &lt; 0 if * the first argument is less than the second; &gt; 0 if the first * argument is greater; and 0 otherwise. (defaults to <code>a - b</code>) * @param {low} the lower bound of the range in <code>array</code> to * search in (defaults to 0) * @param {high} the upper bound of the range in <code>array</code> to * search in (defaults to <code>array.length - 1</code>) */ var ceilingIndex = binarySearch; /** * Finds the entry with the least element greater than or equal to a given search value in a sorted array * using a binary search. If the given value is greater than all elements in the * array, returns [array.length, undefined]. * * @param {array} the array to search in. * @param {find} the value to search for. * @param {comparator} two-argument function that returns &lt; 0 if * the first argument is less than the second; &gt; 0 if the first * argument is greater; and 0 otherwise. (defaults to <code>a - b</code>) * @param {low} the lower bound of the range in <code>array</code> to * search in (defaults to 0) * @param {high} the upper bound of the range in <code>array</code> to * search in (defaults to <code>array.length - 1</code>) */ exports.ceilingIndex = ceilingIndex; function ceilingEntry(array, find) { var comparator = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : DEFAULT_COMPARATOR; var low = arguments.length > 3 ? arguments[3] : undefined; var high = arguments.length > 4 ? arguments[4] : undefined; var index = ceilingIndex(array, find, comparator, low, high); return [index, array[index]]; } /** * Finds the least element greater than or equal to a given search value in a sorted array * using a binary search. If the given value is greater than all elements in the * array, returns undefined. * * @param {array} the array to search in. * @param {find} the value to search for. * @param {comparator} two-argument function that returns &lt; 0 if * the first argument is less than the second; &gt; 0 if the first * argument is greater; and 0 otherwise. (defaults to <code>a - b</code>) * @param {low} the lower bound of the range in <code>array</code> to * search in (defaults to 0) * @param {high} the upper bound of the range in <code>array</code> to * search in (defaults to <code>array.length - 1</code>) */ function ceilingValue(array, find) { var comparator = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : DEFAULT_COMPARATOR; var low = arguments.length > 3 ? arguments[3] : undefined; var high = arguments.length > 4 ? arguments[4] : undefined; var index = ceilingIndex(array, find, comparator, low, high); return array[index]; } /** * Finds the index of the least element greater than a given value in a sorted array * using a binary search. If the given value is greater than or equal to all elements in the * array, returns the length of the array. * * @param {array} the array to search in. * @param {find} the value to search for. * @param {comparator} two-argument function that returns &lt; 0 if * the first argument is less than the second; &gt; 0 if the first * argument is greater; and 0 otherwise. (defaults to <code>a - b</code>) * @param {low} the lower bound of the range in <code>array</code> to * search in (defaults to 0) * @param {high} the upper bound of the range in <code>array</code> to * search in (defaults to <code>array.length - 1</code>) */ function higherIndex(array, find) { var comparator = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : DEFAULT_COMPARATOR; var low = arguments.length > 3 ? arguments[3] : undefined; var high = arguments.length > 4 ? arguments[4] : undefined; var i = binarySearch(array, find, comparator, low, high); return i < array.length && comparator(array[i], find) <= 0 ? i + 1 : i; } /** * Finds the entry with the least element greater than a given value in a sorted array * using a binary search. If the given value is greater than or equal to all elements in the * array, returns [array.length, undefined]. * * @param {array} the array to search in. * @param {find} the value to search for. * @param {comparator} two-argument function that returns &lt; 0 if * the first argument is less than the second; &gt; 0 if the first * argument is greater; and 0 otherwise. (defaults to <code>a - b</code>) * @param {low} the lower bound of the range in <code>array</code> to * search in (defaults to 0) * @param {high} the upper bound of the range in <code>array</code> to * search in (defaults to <code>array.length - 1</code>) */ function higherEntry(array, find) { var comparator = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : DEFAULT_COMPARATOR; var low = arguments.length > 3 ? arguments[3] : undefined; var high = arguments.length > 4 ? arguments[4] : undefined; var index = higherIndex(array, find, comparator, low, high); return [index, array[index]]; } /** * Finds the least element greater than a given value in a sorted array * using a binary search. If the given value is greater than or equal to all elements in the * array, returns undefined. * * @param {array} the array to search in. * @param {find} the value to search for. * @param {comparator} two-argument function that returns &lt; 0 if * the first argument is less than the second; &gt; 0 if the first * argument is greater; and 0 otherwise. (defaults to <code>a - b</code>) * @param {low} the lower bound of the range in <code>array</code> to * search in (defaults to 0) * @param {high} the upper bound of the range in <code>array</code> to * search in (defaults to <code>array.length - 1</code>) */ function higherValue(array, find) { var comparator = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : DEFAULT_COMPARATOR; var low = arguments.length > 3 ? arguments[3] : undefined; var high = arguments.length > 4 ? arguments[4] : undefined; var index = higherIndex(array, find, comparator, low, high); return array[index]; }