mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-31 00:22:30 +00:00
perf(sidebar): 优化侧边栏搜索匹配性能
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
export type SidebarSearchMatchKind = "exact" | "prefix" | "word-prefix" | "substring" | "abbreviation" | "fuzzy";
|
||||
|
||||
export interface SidebarSearchMatch {
|
||||
kind: SidebarSearchMatchKind;
|
||||
score: number;
|
||||
}
|
||||
|
||||
function isWordBoundary(text: string, index: number): boolean {
|
||||
if (index === 0) return true;
|
||||
const prev = text[index - 1];
|
||||
return prev === "_" || prev === "-" || prev === "." || prev === " " || prev === "/" || prev === "\\";
|
||||
}
|
||||
|
||||
function matchesWordPrefix(text: string, query: string): boolean {
|
||||
for (let i = 0; i < text.length; i++) {
|
||||
if (isWordBoundary(text, i) && text.startsWith(query, i)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function matchesAbbreviation(text: string, query: string): boolean {
|
||||
let j = 0;
|
||||
for (let i = 0; i < text.length && j < query.length; i++) {
|
||||
if (isWordBoundary(text, i) && text[i] === query[j]) j++;
|
||||
}
|
||||
return j === query.length;
|
||||
}
|
||||
|
||||
function matchesSubsequence(text: string, query: string): boolean {
|
||||
if (query.length < 2 || query.length > text.length) return false;
|
||||
|
||||
let j = 0;
|
||||
for (let i = 0; i < text.length && j < query.length; i++) {
|
||||
if (text[i] === query[j]) j++;
|
||||
}
|
||||
return j === query.length;
|
||||
}
|
||||
|
||||
export function matchSidebarLabel(label: string, query: string): SidebarSearchMatch | null {
|
||||
if (!query) return null;
|
||||
|
||||
if (label === query) return { kind: "exact", score: 100 };
|
||||
if (label.startsWith(query)) return { kind: "prefix", score: 90 };
|
||||
if (matchesWordPrefix(label, query)) return { kind: "word-prefix", score: 80 };
|
||||
if (label.includes(query)) return { kind: "substring", score: 70 };
|
||||
if (query.length >= 2 && matchesAbbreviation(label, query)) return { kind: "abbreviation", score: 60 };
|
||||
if (matchesSubsequence(label, query)) return { kind: "fuzzy", score: 40 };
|
||||
|
||||
return null;
|
||||
}
|
||||
Reference in New Issue
Block a user