@polgubau/utils
Version:
A collection of utility functions for TypeScript
95 lines • 3.43 kB
JavaScript
// src/functions/fuzzy-finder/fuzzyFinder.ts
var MATCH_CONTINUOUS = 1;
var MATCH_NEW_WORD_SPACE = 0.9;
var MATCH_NEW_WORD_NON_SPACE = 0.8;
var MATCH_CHARACTER_JUMP = 0.17;
var PENALTY_TRANSPOSITION = 0.1;
var PENALTY_SKIPPED_CHAR = 0.999;
var PENALTY_CASE_DIFFERENCE = 0.9999;
var PENALTY_INCOMPLETE_MATCH = 0.99;
var IS_GAP_REGEXP = /[\\\/_+.#"@\[\(\{&]/;
var IS_SPACE_REGEXP = /[\s-]/;
var COUNT_SPACE_REGEXP = /[\s-]/g;
function fuzzyFinderInner(string, abbreviation, lowerString, lowerAbbreviation, stringIndex, abbreviationIndex, memoizedResults) {
if (abbreviationIndex === abbreviation.length) {
if (stringIndex === string.length) {
return MATCH_CONTINUOUS;
}
return PENALTY_INCOMPLETE_MATCH;
}
const memoizeKey = `${stringIndex},${abbreviationIndex}`;
if (memoizedResults[memoizeKey] !== void 0) {
return memoizedResults[memoizeKey];
}
const abbreviationChar = lowerAbbreviation.charAt(abbreviationIndex);
let index = lowerString.indexOf(abbreviationChar, stringIndex);
let highScore = 0;
let score;
let transposedScore;
let spaceBreaks;
while (index >= 0) {
score = fuzzyFinderInner(
string,
abbreviation,
lowerString,
lowerAbbreviation,
index + 1,
abbreviationIndex + 1,
memoizedResults
);
if (score > highScore) {
if (index === stringIndex) {
score *= MATCH_CONTINUOUS;
} else if (IS_GAP_REGEXP.test(string.charAt(index - 1))) {
score *= MATCH_NEW_WORD_NON_SPACE;
} else if (IS_SPACE_REGEXP.test(string.charAt(index - 1))) {
score *= MATCH_NEW_WORD_SPACE;
spaceBreaks = string.slice(stringIndex, index - 1).match(COUNT_SPACE_REGEXP);
if (spaceBreaks && stringIndex > 0) {
score *= PENALTY_SKIPPED_CHAR ** spaceBreaks.length;
}
} else {
score *= MATCH_CHARACTER_JUMP;
if (stringIndex > 0) {
score *= PENALTY_SKIPPED_CHAR ** (index - stringIndex);
}
}
if (string.charAt(index) !== abbreviation.charAt(abbreviationIndex)) {
score *= PENALTY_CASE_DIFFERENCE;
}
}
if (score < PENALTY_TRANSPOSITION && lowerString.charAt(index - 1) === lowerAbbreviation.charAt(abbreviationIndex + 1) || lowerAbbreviation.charAt(abbreviationIndex + 1) === lowerAbbreviation.charAt(abbreviationIndex) && // allow duplicate letters. Ref #7428
lowerString.charAt(index - 1) !== lowerAbbreviation.charAt(abbreviationIndex)) {
transposedScore = fuzzyFinderInner(
string,
abbreviation,
lowerString,
lowerAbbreviation,
index + 1,
abbreviationIndex + 2,
memoizedResults
);
if (transposedScore * PENALTY_TRANSPOSITION > score) {
score = transposedScore * PENALTY_TRANSPOSITION;
}
}
if (score > highScore) {
highScore = score;
}
index = lowerString.indexOf(abbreviationChar, index + 1);
}
memoizedResults[memoizeKey] = highScore;
return highScore;
}
function formatInput(string) {
return string.toLowerCase().replace(COUNT_SPACE_REGEXP, " ");
}
function fuzzyFinder(string, abbreviation, aliases) {
const s = aliases && aliases.length > 0 ? `${`${string} ${aliases.join(" ")}`}` : string;
return fuzzyFinderInner(s, abbreviation, formatInput(string), formatInput(abbreviation), 0, 0, {});
}
export {
fuzzyFinder,
fuzzyFinderInner
};
//# sourceMappingURL=fuzzyFinder.mjs.map