mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 10:12:45 +00:00
51 lines
1.1 KiB
TypeScript
51 lines
1.1 KiB
TypeScript
/**
|
|
* @file
|
|
* @copyright 2020 Aleksej Komarov
|
|
* @license MIT
|
|
*/
|
|
|
|
const binarySearch = <T, U = unknown>(
|
|
getKey: (value: T) => U,
|
|
collection: readonly T[],
|
|
inserting: T,
|
|
): number => {
|
|
if (collection.length === 0) {
|
|
return 0;
|
|
}
|
|
|
|
const insertingKey = getKey(inserting);
|
|
|
|
let [low, high] = [0, collection.length];
|
|
|
|
// Because we have checked if the collection is empty, it's impossible
|
|
// for this to be used before assignment.
|
|
let compare: U = undefined as unknown as U;
|
|
let middle = 0;
|
|
|
|
while (low < high) {
|
|
middle = (low + high) >> 1;
|
|
|
|
compare = getKey(collection[middle]);
|
|
|
|
if (compare < insertingKey) {
|
|
low = middle + 1;
|
|
} else if (compare === insertingKey) {
|
|
return middle;
|
|
} else {
|
|
high = middle;
|
|
}
|
|
}
|
|
|
|
return compare > insertingKey ? middle : middle + 1;
|
|
};
|
|
|
|
export const binaryInsertWith = <T, U = unknown>(
|
|
collection: readonly T[],
|
|
value: T,
|
|
getKey: (value: T) => U,
|
|
): T[] => {
|
|
const copy = [...collection];
|
|
copy.splice(binarySearch(getKey, collection, value), 0, value);
|
|
return copy;
|
|
};
|