Skip to content

Commit 342f931

Browse files
committed
refactor: drop sortedLastIndex, sortedIndexBy, sortedLastIndexBy
1 parent 8dc4b77 commit 342f931

File tree

8 files changed

+177
-7
lines changed

8 files changed

+177
-7
lines changed

src/common/error-utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { ParseError, VDocumentFragment } from "../ast/index"
2-
import { sortedIndexBy } from "lodash-es"
2+
import { sortedIndexBy } from "../utils/utils"
33
/**
44
* Insert the given error.
55
* @param document The document that the node is belonging to.

src/common/lines-and-columns.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { sortedLastIndex } from "lodash-es"
1+
import { sortedLastIndex } from "../utils/utils"
22
import type { Location } from "../ast/index"
33
import type { LocationCalculator } from "./location-calculator"
44
/**

src/common/location-calculator.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* @copyright 2017 Toru Nagashima. All rights reserved.
44
* See LICENSE file in root directory for full license.
55
*/
6-
import { sortedLastIndex } from "lodash-es"
6+
import { sortedLastIndex } from "../utils/utils"
77
import type { Location } from "../ast/index"
88
import { LinesAndColumns } from "./lines-and-columns"
99

src/common/token-utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { sortedIndexBy, sortedLastIndexBy } from "lodash-es"
1+
import { sortedIndexBy, sortedLastIndexBy } from "../utils/utils"
22
import type { LocationRange, Token, VDocumentFragment } from "../ast/index"
33
import type { LinesAndColumns } from "./lines-and-columns"
44

src/external/token-store/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* @fileoverview Define utilify functions for token store.
33
* @author Toru Nagashima
44
*/
5-
import { sortedIndexBy } from "lodash-es"
5+
import { sortedIndexBy } from "../../utils/utils"
66
import type { HasLocation } from "../../ast/index"
77

88
/**

src/html/parser.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ import {
5050
getScriptParser,
5151
getParserLangFromSFC,
5252
} from "../common/parser-options"
53-
import { sortedIndexBy, sortedLastIndexBy } from "lodash-es"
53+
import { sortedIndexBy, sortedLastIndexBy } from "../utils/utils"
5454
import type {
5555
CustomTemplateTokenizer,
5656
CustomTemplateTokenizerConstructor,

src/script/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* @copyright 2017 Toru Nagashima. All rights reserved.
44
* See LICENSE file in root directory for full license.
55
*/
6-
import { sortedIndexBy } from "lodash-es"
6+
import { sortedIndexBy } from "../utils/utils"
77
import type {
88
ESLintArrayExpression,
99
ESLintArrayPattern,

src/utils/utils.ts

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,173 @@
44
export function camelize(str: string) {
55
return str.replace(/-(\w)/gu, (_, c) => (c ? c.toUpperCase() : ""))
66
}
7+
8+
/**
9+
* A binary search implementation that finds the index at which `predicate`
10+
* stops returning `true` and starts returning `false` (consistently) when run
11+
* on the items of the array. It **assumes** that mapping the array via the
12+
* predicate results in the shape `[...true[], ...false[]]`. *For any other case
13+
* the result is unpredictable*.
14+
*
15+
* This is the base implementation of the `sortedIndex` functions which define
16+
* the predicate for the user, for common use-cases.
17+
*
18+
* It is similar to `findIndex`, but runs at O(logN), whereas the latter is
19+
* general purpose function which runs on any array and predicate, but runs at
20+
* O(N) time.
21+
*
22+
* MIT License | Copyright (c) 2018 remeda | https://remedajs.com/
23+
*
24+
* The implementation is copied from remeda package:
25+
* https://github.com/remeda/remeda/blob/df5fe74841c07bc356bbaa2c89bc7ba0cafafd0a/packages/remeda/src/internal/binarySearchCutoffIndex.ts#L15
26+
*/
27+
function binarySearchCutoffIndex<T>(
28+
array: readonly T[],
29+
predicate: (value: T, index: number, data: readonly T[]) => boolean,
30+
): number {
31+
let lowIndex = 0
32+
let highIndex = array.length
33+
34+
while (lowIndex < highIndex) {
35+
const pivotIndex = (lowIndex + highIndex) >>> 1
36+
const pivot = array[pivotIndex]
37+
38+
if (predicate(pivot, pivotIndex, array)) {
39+
lowIndex = pivotIndex + 1
40+
} else {
41+
highIndex = pivotIndex
42+
}
43+
}
44+
45+
return highIndex
46+
}
47+
48+
/**
49+
* Find the insertion position (index) of an item in an array with items sorted
50+
* in ascending order; so that `splice(sortedIndex, 0, item)` would result in
51+
* maintaining the array's sort-ness. The array can contain duplicates.
52+
* If the item already exists in the array the index would be of the *last*
53+
* occurrence of the item.
54+
*
55+
* Runs in O(logN) time.
56+
*
57+
* @param item - The item to insert.
58+
* @returns Insertion index (In the range 0..data.length).
59+
* @signature
60+
* R.sortedLastIndex(item)(data)
61+
* @example
62+
* R.pipe(['a','a','b','c','c'], sortedLastIndex('c')) // => 5
63+
*
64+
* MIT License | Copyright (c) 2018 remeda | https://remedajs.com/
65+
*
66+
* The implementation is copied from remeda package:
67+
* https://github.com/remeda/remeda/blob/df5fe74841c07bc356bbaa2c89bc7ba0cafafd0a/packages/remeda/src/sortedLastIndex.ts#L51
68+
*/
69+
export function sortedLastIndex<T>(array: readonly T[], item: T): number {
70+
return binarySearchCutoffIndex(array, (pivot) => pivot <= item)
71+
}
72+
73+
/**
74+
* Find the insertion position (index) of an item in an array with items sorted
75+
* in ascending order using a value function; so that
76+
* `splice(sortedIndex, 0, item)` would result in maintaining the arrays sort-
77+
* ness. The array can contain duplicates.
78+
* If the item already exists in the array the index would be of the *first*
79+
* occurrence of the item.
80+
*
81+
* Runs in O(logN) time.
82+
*
83+
* See also:
84+
* * `findIndex` - scans a possibly unsorted array in-order (linear search).
85+
* * `sortedIndex` - like this function, but doesn't take a callbackfn.
86+
* * `sortedLastIndexBy` - like this function, but finds the last suitable index.
87+
* * `sortedLastIndex` - like `sortedIndex`, but finds the last suitable index.
88+
* * `rankBy` - scans a possibly unsorted array in-order, returning the index based on a sorting criteria.
89+
*
90+
* @param data - The (ascending) sorted array.
91+
* @param item - The item to insert.
92+
* @param valueFunction - All comparisons would be performed on the result of
93+
* calling this function on each compared item. Preferably this function should
94+
* return a `number` or `string`. This function should be the same as the one
95+
* provided to sortBy to sort the array. The function is called exactly once on
96+
* each items that is compared against in the array, and once at the beginning
97+
* on `item`. When called on `item` the `index` argument is `undefined`.
98+
* @returns Insertion index (In the range 0..data.length).
99+
* @signature
100+
* R.sortedIndexBy(data, item, valueFunction)
101+
* @example
102+
* R.sortedIndexBy([{age:20},{age:22}],{age:21},prop('age')) // => 1
103+
*
104+
* MIT License | Copyright (c) 2018 remeda | https://remedajs.com/
105+
*
106+
* The implementation is copied from remeda package:
107+
* https://github.com/remeda/remeda/blob/df5fe74841c07bc356bbaa2c89bc7ba0cafafd0a/packages/remeda/src/sortedIndexBy.ts#L37
108+
*/
109+
export function sortedIndexBy<T>(
110+
array: readonly T[],
111+
item: T,
112+
valueFunction: (
113+
item: T,
114+
index: number | undefined,
115+
data: readonly T[],
116+
) => number,
117+
): number {
118+
const value = valueFunction(item, undefined, array)
119+
120+
return binarySearchCutoffIndex(
121+
array,
122+
(pivot, index) => valueFunction(pivot, index, array) < value,
123+
)
124+
}
125+
126+
/**
127+
* Find the insertion position (index) of an item in an array with items sorted
128+
* in ascending order using a value function; so that
129+
* `splice(sortedIndex, 0, item)` would result in maintaining the arrays sort-
130+
* ness. The array can contain duplicates.
131+
* If the item already exists in the array the index would be of the *last*
132+
* occurrence of the item.
133+
*
134+
* Runs in O(logN) time.
135+
*
136+
* See also:
137+
* * `findIndex` - scans a possibly unsorted array in-order (linear search).
138+
* * `sortedLastIndex` - a simplified version of this function, without a callbackfn.
139+
* * `sortedIndexBy` - like this function, but returns the first suitable index.
140+
* * `sortedIndex` - like `sortedLastIndex` but without a callbackfn.
141+
* * `rankBy` - scans a possibly unsorted array in-order, returning the index based on a sorting criteria.
142+
*
143+
* @param data - The (ascending) sorted array.
144+
* @param item - The item to insert.
145+
* @param valueFunction - All comparisons would be performed on the result of
146+
* calling this function on each compared item. Preferably this function should
147+
* return a `number` or `string`. This function should be the same as the one
148+
* provided to sortBy to sort the array. The function is called exactly once on
149+
* each items that is compared against in the array, and once at the beginning
150+
* on `item`. When called on `item` the `index` argument is `undefined`.
151+
* @returns Insertion index (In the range 0..data.length).
152+
* @signature
153+
* R.sortedLastIndexBy(data, item, valueFunction)
154+
* @example
155+
* R.sortedLastIndexBy([{age:20},{age:22}],{age:21},prop('age')) // => 1
156+
* MIT License | Copyright (c) 2018 remeda | https://remedajs.com/
157+
*
158+
* The implementation is copied from remeda package:
159+
* https://github.com/remeda/remeda/blob/df5fe74841c07bc356bbaa2c89bc7ba0cafafd0a/packages/remeda/src/sortedLastIndexBy.ts#L37
160+
*/
161+
export function sortedLastIndexBy<T>(
162+
array: readonly T[],
163+
item: T,
164+
valueFunction: (
165+
item: T,
166+
index: number | undefined,
167+
data: readonly T[],
168+
) => number,
169+
): number {
170+
const value = valueFunction(item, undefined, array)
171+
172+
return binarySearchCutoffIndex(
173+
array,
174+
(pivot, index) => valueFunction(pivot, index, array) <= value,
175+
)
176+
}

0 commit comments

Comments
 (0)