diff --git a/src/dragAndDropHandler/binarySearch.ts b/src/dragAndDropHandler/binarySearch.ts new file mode 100644 index 00000000..18f2937f --- /dev/null +++ b/src/dragAndDropHandler/binarySearch.ts @@ -0,0 +1,27 @@ +function binarySearch(items: T[], compareFn: (a: T) => number): null | T { + let low = 0; + let high = items.length; + + while (low < high) { + const mid = (low + high) >> 1; + const item = items[mid]; + + if (item === undefined) { + return null; + } + + const compareResult = compareFn(item); + + if (compareResult > 0) { + high = mid; + } else if (compareResult < 0) { + low = mid + 1; + } else { + return item; + } + } + + return null; +} + +export default binarySearch; diff --git a/src/dragAndDropHandler/index.ts b/src/dragAndDropHandler/index.ts index 692c9657..d339bc03 100644 --- a/src/dragAndDropHandler/index.ts +++ b/src/dragAndDropHandler/index.ts @@ -16,6 +16,7 @@ import { Node } from "../node"; import NodeElement from "../nodeElement"; import { getPositionName, Position } from "../position"; import { getElementPosition } from "../util"; +import binarySearch from "./binarySearch"; import DragElement from "./dragElement"; import generateHitAreas from "./generateHitAreas"; import { DropHint, HitArea } from "./types"; @@ -143,26 +144,15 @@ export class DragAndDropHandler { return null; } - let low = 0; - let high = this.hitAreas.length; - while (low < high) { - const mid = (low + high) >> 1; - const area = this.hitAreas[mid]; - - if (!area) { - return null; - } - + return binarySearch(this.hitAreas, (area) => { if (y < area.top) { - high = mid; + return 1; } else if (y > area.bottom) { - low = mid + 1; + return -1; } else { - return area; + return 0; } - } - - return null; + }); } private generateHitAreas(): void { diff --git a/src/test/dragAndDropHandler/binarySearch.test.ts b/src/test/dragAndDropHandler/binarySearch.test.ts new file mode 100644 index 00000000..a31ac722 --- /dev/null +++ b/src/test/dragAndDropHandler/binarySearch.test.ts @@ -0,0 +1,31 @@ +import binarySearch from "../../dragAndDropHandler/binarySearch"; + +it("returns null when the array is empty", () => { + const compareFn = (_item: number) => 0; + + const result = binarySearch([], compareFn); + expect(result).toBeNull(); +}); + +it("finds a value", () => { + const compareFn = (item: number) => item - 5; + + const result = binarySearch([1, 5, 7, 9], compareFn); + expect(result).toEqual(5); +}); + +it("returns null when the value doesn't exist", () => { + const compareFn = (item: number) => item - 6; + + const result = binarySearch([1, 5, 7, 9], compareFn); + expect(result).toBeNull(); +}); + +it("handles undefined values in the array", () => { + const compareFn = (item: number) => item - 6; + const array = [1, 5, 7, 9]; + (array as any)[1] = undefined; + + const result = binarySearch(array, compareFn); + expect(result).toBeNull(); +});