Skip to content
This repository has been archived by the owner on Dec 5, 2023. It is now read-only.

Commit

Permalink
Add a cache to reduce time-complexity of fuzzySuggest
Browse files Browse the repository at this point in the history
in the case where there are many repeated characters.
  • Loading branch information
ConradIrwin committed Jul 27, 2011
1 parent 0fbf80c commit e3123b4
Showing 1 changed file with 36 additions and 23 deletions.
59 changes: 36 additions & 23 deletions jquery.fuzzymatch.js
Expand Up @@ -104,6 +104,9 @@
* @param abbreviation, an abbreviation that a user may have typed * @param abbreviation, an abbreviation that a user may have typed
* in order to specify that string. * in order to specify that string.
* *
* @cache (private), a cache that reduces the expected running time of the
* algorithm in the case there are many repeated characters.
*
* @return { * @return {
* score: A score (0 <= score <= 1) that indicates how likely it is that * score: A score (0 <= score <= 1) that indicates how likely it is that
* the abbreviation matches the string. * the abbreviation matches the string.
Expand All @@ -122,48 +125,58 @@
* *
* } * }
**/ **/
$.fuzzyMatch = function (string, abbreviation) { $.fuzzyMatch = function (string, abbreviation, cache) {
if (abbreviation === "") { if (abbreviation === "") {
return { return {
score: string === "" ? SCORE_CONTINUE_MATCH : PENALTY_NOT_COMPLETE, score: string === "" ? SCORE_CONTINUE_MATCH : PENALTY_NOT_COMPLETE,
html: $('<div>').text(string).html() html: $('<div>').text(string).html()
}; };
} }


return $(allCaseInsensitiveSplits(string, abbreviation.charAt(0))) if (cache && cache[string] && cache[string][abbreviation]) {
.map(function (i, split) { return $.extend({}, cache[string][abbreviation]);
var result = $.fuzzyMatch(split.after, abbreviation.slice(1)), }
preceding_char = split.before.charAt(split.before.length - 1);
cache = cache || {};
cache[string] = cache[string] || {};
cache[string][abbreviation] =


if (split.before === "") { $(allCaseInsensitiveSplits(string, abbreviation.charAt(0)))
result.score *= SCORE_CONTINUE_MATCH; .map(function (i, split) {
var result = $.fuzzyMatch(split.after, abbreviation.slice(1), cache),
preceding_char = split.before.charAt(split.before.length - 1);


} else if (preceding_char.match(/[\\\/\-_+.# \t"@\[\(\{&]/) || if (split.before === "") {
(split.chr.toLowerCase() !== split.chr && preceding_char.toLowerCase() === preceding_char)) { result.score *= SCORE_CONTINUE_MATCH;


result.score *= SCORE_START_WORD; } else if (preceding_char.match(/[\\\/\-_+.# \t"@\[\(\{&]/) ||
} else { (split.chr.toLowerCase() !== split.chr && preceding_char.toLowerCase() === preceding_char)) {
result.score *= SCORE_OK;
}


if (split.chr !== abbreviation.charAt(0)) { result.score *= SCORE_START_WORD;
result.score *= PENALTY_CASE_MISMATCH; } else {
} result.score *= SCORE_OK;
}


result.score *= Math.pow(PENALTY_SKIPPED, split.before.length); if (split.chr !== abbreviation.charAt(0)) {
result.html = $('<div>').text(split.before).append($('<b>').text(split.chr)).append(result.html).html(); result.score *= PENALTY_CASE_MISMATCH;
}


return result; result.score *= Math.pow(PENALTY_SKIPPED, split.before.length);
}) result.html = $('<div>').text(split.before).append($('<b>').text(split.chr)).append(result.html).html();
.sort(function (a, b) {
return a.score < b.score ? 1 : a.score === b.score ? 0 : -1; return result;
})[0] || })
.sort(function (a, b) {
return a.score < b.score ? 1 : a.score === b.score ? 0 : -1;
})[0] ||


// No matches for the next character in the abbreviation, abort! // No matches for the next character in the abbreviation, abort!
{ {
score: 0, // This 0 will multiply up to the top, giving a total of 0 score: 0, // This 0 will multiply up to the top, giving a total of 0
html: $('<div>').text(string).html() html: $('<div>').text(string).html()
}; };

return $.extend({}, cache[string][abbreviation]);
}; };
/*global jQuery */ /*global jQuery */
}(jQuery)); }(jQuery));

0 comments on commit e3123b4

Please sign in to comment.