diff --git a/packages/arrays/src/binary-search.ts b/packages/arrays/src/binary-search.ts index ec1887d877..9b1449c820 100644 --- a/packages/arrays/src/binary-search.ts +++ b/packages/arrays/src/binary-search.ts @@ -1,10 +1,10 @@ import { Comparator, Fn } from "@thi.ng/api"; -import { compare } from "@thi.ng/compare"; +import { compare, compareNumAsc } from "@thi.ng/compare"; /** * Returns the supposed index of `x` in pre-sorted array-like collection * `buf`. If `x` can't be found, returns `-index-1`, representing the - * negative of the index were `x` to be inserted into `buf`. E.g if the + * negative of the index, were `x` to be inserted into `buf`. E.g if the * return value is -3, `x` would appear/insert at index 2. * * ``` @@ -46,3 +46,33 @@ export const binarySearch = ( } return -low - 1; }; + +/** + * Similar to `binarySearch()`, but optimized for numeric arrays and + * supporting custom comparators (default: `compareNumAsc` from + * thi.ng/compare pkg). + * + * @param buf + * @param x + * @param cmp + */ +export const binarySearchNumeric = ( + buf: ArrayLike, + x: number, + cmp: Comparator = compareNumAsc +) => { + let low = 0; + let high = buf.length - 1; + while (low <= high) { + const mid = (low + high) >>> 1; + const c = cmp(buf[mid], x); + if (c < 0) { + low = mid + 1; + } else if (c > 0) { + high = mid - 1; + } else { + return mid; + } + } + return -low - 1; +};