UNPKG

@polgubau/utils

Version:

A collection of utility functions for TypeScript

95 lines 3.43 kB
// 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