@jcoreio/precise-bs
Version:
binary search and related utility functions
312 lines (301 loc) • 14.6 kB
JavaScript
"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 < 0 if
* the first argument is less than the second; > 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 < 0 if
* the first argument is less than the second; > 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 < 0 if
* the first argument is less than the second; > 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 < 0 if
* the first argument is less than the second; > 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 < 0 if
* the first argument is less than the second; > 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 < 0 if
* the first argument is less than the second; > 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 < 0 if
* the first argument is less than the second; > 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 < 0 if
* the first argument is less than the second; > 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 < 0 if
* the first argument is less than the second; > 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 < 0 if
* the first argument is less than the second; > 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 < 0 if
* the first argument is less than the second; > 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 < 0 if
* the first argument is less than the second; > 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];
}