21 lines
792 B
TypeScript
21 lines
792 B
TypeScript
|
|
/** Normalize a display name for comparison: lowercase, strip punctuation, collapse whitespace. */
|
||
|
|
export function normalizeName(name: string): string {
|
||
|
|
return name.toLowerCase().replace(/[^a-z0-9\s]/g, '').replace(/\s+/g, ' ').trim();
|
||
|
|
}
|
||
|
|
|
||
|
|
function bigrams(s: string): string[] {
|
||
|
|
const result: string[] = [];
|
||
|
|
for (let i = 0; i < s.length - 1; i++) result.push(s.slice(i, i + 2));
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
/** Bigram Dice coefficient — returns similarity in [0, 1]. */
|
||
|
|
export function diceCoefficient(a: string, b: string): number {
|
||
|
|
if (a === b) return 1;
|
||
|
|
if (a.length < 2 || b.length < 2) return 0;
|
||
|
|
const bigA = bigrams(a);
|
||
|
|
const bigB = new Set(bigrams(b));
|
||
|
|
const intersection = bigA.filter((bg) => bigB.has(bg)).length;
|
||
|
|
return (2 * intersection) / (bigA.length + bigB.size);
|
||
|
|
}
|