mirror of
https://github.com/streetwriters/notesnook.git
synced 2026-05-18 13:16:11 +02:00
core: normalize special separators in fuzzy search (#9541)
Signed-off-by: 01zulfi <85733202+01zulfi@users.noreply.github.com>
This commit is contained in:
@@ -93,4 +93,25 @@ describe("lookup.fuzzy", () => {
|
||||
).toStrictEqual([{ id: "1", title: "hello-suffix" }]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("separator normalization", () => {
|
||||
const items = [
|
||||
{ id: "1", title: "file search.jpg" },
|
||||
{ id: "2", title: "file-search.jpg" },
|
||||
{ id: "3", title: "file_search.jpg" }
|
||||
];
|
||||
|
||||
test("query with space matches all separator variants", () => {
|
||||
const result = fuzzy("file search", items, (i) => i.id, { title: 1 });
|
||||
expect(result).toStrictEqual(items);
|
||||
});
|
||||
|
||||
test("query with special character between words matches all separator variants", () => {
|
||||
let result = fuzzy("file_search", items, (i) => i.id, { title: 1 });
|
||||
expect(result).toStrictEqual(items);
|
||||
|
||||
result = fuzzy("file-search", items, (i) => i.id, { title: 1 });
|
||||
expect(result).toStrictEqual(items);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -20,6 +20,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
import { match, surround } from "fuzzyjs";
|
||||
import { clone } from "./clone.js";
|
||||
|
||||
const SEPARATORS = /(?<=\w)[^a-zA-Z0-9](?=\w)/g;
|
||||
|
||||
function normalizeSeparators(str: string): string {
|
||||
return str.replace(SEPARATORS, " ");
|
||||
}
|
||||
|
||||
function hasSeparator(str: string): boolean {
|
||||
const result = SEPARATORS.test(str);
|
||||
SEPARATORS.lastIndex = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
export function fuzzy<T>(
|
||||
query: string,
|
||||
items: T[],
|
||||
@@ -39,13 +51,20 @@ export function fuzzy<T>(
|
||||
}
|
||||
> = new Map();
|
||||
|
||||
const shouldNormalize = hasSeparator(query);
|
||||
const finalQuery = shouldNormalize ? normalizeSeparators(query) : query;
|
||||
|
||||
for (const item of items) {
|
||||
if (options.limit && results.size >= options.limit) break;
|
||||
|
||||
const identifier = getIdentifier(item);
|
||||
|
||||
for (const field in fields) {
|
||||
const result = match(query, `${item[field]}`);
|
||||
const value = `${item[field]}`;
|
||||
const result = match(
|
||||
finalQuery,
|
||||
shouldNormalize ? normalizeSeparators(value) : value
|
||||
);
|
||||
if (!result.match) continue;
|
||||
|
||||
const oldMatch = results.get(identifier);
|
||||
|
||||
Reference in New Issue
Block a user