nano-binary-search 1.0.10 → 1.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -4
- package/index.js +14 -0
- package/llms.txt +55 -0
- package/package.json +15 -5
package/README.md
CHANGED
|
@@ -9,10 +9,38 @@ because it is done right and fits JavaScript — it is ripe for code reuse.
|
|
|
9
9
|
|
|
10
10
|
For TypeScript users the typings are included.
|
|
11
11
|
|
|
12
|
+
This is equivalent to C++ `std::lower_bound` / Python `bisect.bisect_left`.
|
|
13
|
+
|
|
14
|
+
## Quick reference
|
|
15
|
+
|
|
16
|
+
```js
|
|
17
|
+
import binarySearch from 'nano-binary-search';
|
|
18
|
+
|
|
19
|
+
// Lower bound (first element >= value):
|
|
20
|
+
binarySearch([1, 2, 4, 5], x => x < 3); // → 2
|
|
21
|
+
|
|
22
|
+
// Upper bound (first element > value):
|
|
23
|
+
binarySearch([1, 2, 4, 5], x => x <= 2); // → 2
|
|
24
|
+
|
|
25
|
+
// Insert keeping sorted order:
|
|
26
|
+
const idx = binarySearch(sortedArray, x => x < value);
|
|
27
|
+
sortedArray.splice(idx, 0, value);
|
|
28
|
+
|
|
29
|
+
// Remove all elements equal to value:
|
|
30
|
+
const lo = binarySearch(sortedArray, x => x < value);
|
|
31
|
+
const hi = binarySearch(sortedArray, x => x <= value, lo);
|
|
32
|
+
sortedArray.splice(lo, hi - lo);
|
|
33
|
+
|
|
34
|
+
// Edge cases — just work:
|
|
35
|
+
binarySearch([], x => x < 5); // → 0 (empty array)
|
|
36
|
+
binarySearch([1, 2, 3], x => x < 1); // → 0 (before all)
|
|
37
|
+
binarySearch([1, 2, 3], x => x < 4); // → 3 (after all)
|
|
38
|
+
```
|
|
39
|
+
|
|
12
40
|
## Why?
|
|
13
41
|
|
|
14
42
|
Why do I think it is done right? Because it supports important invariants with
|
|
15
|
-
[splice()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/
|
|
43
|
+
[splice()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice).
|
|
16
44
|
|
|
17
45
|
### No need to worry about inserting values
|
|
18
46
|
|
|
@@ -70,7 +98,7 @@ const index: number = binarySearch<T>(
|
|
|
70
98
|
lessFn: (value: T, index: number, array: readonly T[]) => boolean,
|
|
71
99
|
l: number = 0,
|
|
72
100
|
r: number = sortedArray.length
|
|
73
|
-
):
|
|
101
|
+
): number;
|
|
74
102
|
```
|
|
75
103
|
|
|
76
104
|
- Inputs:
|
|
@@ -85,8 +113,8 @@ const index: number = binarySearch<T>(
|
|
|
85
113
|
|
|
86
114
|
The function return an index, where we can safely insert the searched value with `splice()`:
|
|
87
115
|
|
|
88
|
-
- if we used `<` operator as the comparison function, the index will point to the first value that is greater or equal than the searched value.
|
|
89
|
-
- if we used `<=` operator as the comparison function, the index will point to the first value that is greater than the searched value.
|
|
116
|
+
- if we used `<` operator as the comparison function, the index will point to the first value that is greater or equal than the searched value (**lower bound**, like C++ `std::lower_bound` or Python `bisect_left`).
|
|
117
|
+
- if we used `<=` operator as the comparison function, the index will point to the first value that is greater than the searched value (**upper bound**, like C++ `std::upper_bound` or Python `bisect_right`).
|
|
90
118
|
|
|
91
119
|
That's all Folks!
|
|
92
120
|
|
|
@@ -144,6 +172,7 @@ This project is licensed under the BSD-3-Clause license.
|
|
|
144
172
|
|
|
145
173
|
## Release history
|
|
146
174
|
|
|
175
|
+
- 1.0.11 _Technical release: more tests to increase coverage, more AI-friendly changes_
|
|
147
176
|
- 1.0.10 _Updated dev deps_
|
|
148
177
|
- 1.0.9 _Updated dev deps_
|
|
149
178
|
- 1.0.8 _Updated dev deps_
|
package/index.js
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
'use strict';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Binary search (lower bound). Equivalent to C++ `std::lower_bound` / Python `bisect.bisect_left`.
|
|
7
|
+
*
|
|
8
|
+
* Returns an insertion index compatible with `Array.prototype.splice()`.
|
|
9
|
+
* - With `<`: returns the index of the first element ≥ pivot (lower bound).
|
|
10
|
+
* - With `<=`: returns the index of the first element > pivot (upper bound).
|
|
11
|
+
*
|
|
12
|
+
* @template T
|
|
13
|
+
* @param {readonly T[]} sortedArray - sorted array of values.
|
|
14
|
+
* @param {(value: T, index: number, array: readonly T[]) => boolean} lessFn - returns true if value < pivot.
|
|
15
|
+
* @param {number} [l=0] - left index (inclusive).
|
|
16
|
+
* @param {number} [r=sortedArray.length] - right index (exclusive).
|
|
17
|
+
* @returns {number} insertion index.
|
|
18
|
+
*/
|
|
5
19
|
export const binarySearch = (sortedArray, lessFn, l = 0, r = sortedArray.length) => {
|
|
6
20
|
while (l < r) {
|
|
7
21
|
const m = l + Math.floor((r - l) / 2);
|
package/llms.txt
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# nano-binary-search
|
|
2
|
+
|
|
3
|
+
> Binary search for JavaScript done right. Zero dependencies, single file.
|
|
4
|
+
> Equivalent to C++ `std::lower_bound` / Python `bisect.bisect_left`.
|
|
5
|
+
|
|
6
|
+
## Install
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
npm install nano-binary-search
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Usage
|
|
13
|
+
|
|
14
|
+
```js
|
|
15
|
+
import binarySearch from 'nano-binary-search';
|
|
16
|
+
|
|
17
|
+
// Find insertion point (lower bound): index of first element >= value
|
|
18
|
+
const index = binarySearch(sortedArray, x => x < value);
|
|
19
|
+
sortedArray.splice(index, 0, value); // insert keeping sorted order
|
|
20
|
+
|
|
21
|
+
// Find upper bound: index of first element > value
|
|
22
|
+
const upper = binarySearch(sortedArray, x => x <= value);
|
|
23
|
+
|
|
24
|
+
// Find and remove all elements equal to value
|
|
25
|
+
const lo = binarySearch(sortedArray, x => x < value);
|
|
26
|
+
const hi = binarySearch(sortedArray, x => x <= value, lo);
|
|
27
|
+
sortedArray.splice(lo, hi - lo);
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## API
|
|
31
|
+
|
|
32
|
+
`binarySearch(sortedArray, lessFn, l?, r?)` → `number`
|
|
33
|
+
|
|
34
|
+
- `sortedArray` — sorted array of values of type `T`.
|
|
35
|
+
- `lessFn(value: T, index: number, array: readonly T[])` — returns `true` if `value` is less than the pivot. The comparison function.
|
|
36
|
+
- `l` — left index, inclusive. Defaults to `0`.
|
|
37
|
+
- `r` — right index, exclusive. Defaults to `sortedArray.length`.
|
|
38
|
+
- Returns: insertion index compatible with `Array.prototype.splice()`.
|
|
39
|
+
|
|
40
|
+
## Key properties
|
|
41
|
+
|
|
42
|
+
- With `<` in lessFn: returns index of first element ≥ pivot (**lower bound**).
|
|
43
|
+
- With `<=` in lessFn: returns index of first element > pivot (**upper bound**).
|
|
44
|
+
- Works correctly with empty arrays, sub-ranges, duplicate values, and custom comparators.
|
|
45
|
+
- The result is always a valid `splice()` index — no off-by-one errors.
|
|
46
|
+
|
|
47
|
+
## Examples with results
|
|
48
|
+
|
|
49
|
+
```js
|
|
50
|
+
binarySearch([1, 2, 4, 5], x => x < 3) // → 2 (insert 3 at index 2)
|
|
51
|
+
binarySearch([1, 2, 4, 5], x => x <= 2) // → 2 (upper bound of 2)
|
|
52
|
+
binarySearch([], x => x < 5) // → 0 (empty array)
|
|
53
|
+
binarySearch([1, 2, 3], x => x < 1) // → 0 (before all)
|
|
54
|
+
binarySearch([1, 2, 3], x => x < 4) // → 3 (after all)
|
|
55
|
+
```
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nano-binary-search",
|
|
3
3
|
"description": "Binary search for JavaScript done right.",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.11",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"types": "index.d.ts",
|
|
@@ -40,14 +40,24 @@
|
|
|
40
40
|
"homepage": "https://github.com/uhop/nano-binary-search#readme",
|
|
41
41
|
"keywords": [
|
|
42
42
|
"binary search",
|
|
43
|
-
"algorithm"
|
|
43
|
+
"algorithm",
|
|
44
|
+
"sorted array",
|
|
45
|
+
"insertion point",
|
|
46
|
+
"lower bound",
|
|
47
|
+
"upper bound",
|
|
48
|
+
"bisect",
|
|
49
|
+
"search",
|
|
50
|
+
"splice",
|
|
51
|
+
"zero dependencies",
|
|
52
|
+
"lightweight"
|
|
44
53
|
],
|
|
45
54
|
"author": "Eugene Lazutkin <eugene.lazutkin@gmail.com> (https://www.lazutkin.com/)",
|
|
46
55
|
"license": "BSD-3-Clause",
|
|
47
56
|
"files": [
|
|
48
57
|
"index.*",
|
|
49
58
|
"LICENSE",
|
|
50
|
-
"README.md"
|
|
59
|
+
"README.md",
|
|
60
|
+
"llms.txt"
|
|
51
61
|
],
|
|
52
62
|
"tape6": {
|
|
53
63
|
"tests": [
|
|
@@ -61,8 +71,8 @@
|
|
|
61
71
|
}
|
|
62
72
|
},
|
|
63
73
|
"devDependencies": {
|
|
64
|
-
"tape-six": "^1.7.
|
|
65
|
-
"tape-six-proc": "^1.2.
|
|
74
|
+
"tape-six": "^1.7.2",
|
|
75
|
+
"tape-six-proc": "^1.2.3",
|
|
66
76
|
"typescript": "^5.9.3"
|
|
67
77
|
}
|
|
68
78
|
}
|