Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add a cache to reduce time-complexity of fuzzySuggest

in the case where there are many repeated characters.
  • Loading branch information...
commit e3123b42a32cb346678cf1d82eddf6286ced697f 1 parent 0fbf80c
@ConradIrwin ConradIrwin authored
Showing with 36 additions and 23 deletions.
  1. +36 −23 jquery.fuzzymatch.js
View
59 jquery.fuzzymatch.js
@@ -104,6 +104,9 @@
* @param abbreviation, an abbreviation that a user may have typed
* 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 {
* score: A score (0 <= score <= 1) that indicates how likely it is that
* the abbreviation matches the string.
@@ -122,7 +125,7 @@
*
* }
**/
- $.fuzzyMatch = function (string, abbreviation) {
+ $.fuzzyMatch = function (string, abbreviation, cache) {
if (abbreviation === "") {
return {
score: string === "" ? SCORE_CONTINUE_MATCH : PENALTY_NOT_COMPLETE,
@@ -130,40 +133,50 @@
};
}
- return $(allCaseInsensitiveSplits(string, abbreviation.charAt(0)))
- .map(function (i, split) {
- var result = $.fuzzyMatch(split.after, abbreviation.slice(1)),
- preceding_char = split.before.charAt(split.before.length - 1);
+ if (cache && cache[string] && cache[string][abbreviation]) {
+ return $.extend({}, cache[string][abbreviation]);
+ }
+
+ cache = cache || {};
+ cache[string] = cache[string] || {};
+ cache[string][abbreviation] =
- if (split.before === "") {
- result.score *= SCORE_CONTINUE_MATCH;
+ $(allCaseInsensitiveSplits(string, abbreviation.charAt(0)))
+ .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"@\[\(\{&]/) ||
- (split.chr.toLowerCase() !== split.chr && preceding_char.toLowerCase() === preceding_char)) {
+ if (split.before === "") {
+ result.score *= SCORE_CONTINUE_MATCH;
- result.score *= SCORE_START_WORD;
- } else {
- result.score *= SCORE_OK;
- }
+ } else if (preceding_char.match(/[\\\/\-_+.# \t"@\[\(\{&]/) ||
+ (split.chr.toLowerCase() !== split.chr && preceding_char.toLowerCase() === preceding_char)) {
- if (split.chr !== abbreviation.charAt(0)) {
- result.score *= PENALTY_CASE_MISMATCH;
- }
+ result.score *= SCORE_START_WORD;
+ } else {
+ result.score *= SCORE_OK;
+ }
- result.score *= Math.pow(PENALTY_SKIPPED, split.before.length);
- result.html = $('<div>').text(split.before).append($('<b>').text(split.chr)).append(result.html).html();
+ if (split.chr !== abbreviation.charAt(0)) {
+ result.score *= PENALTY_CASE_MISMATCH;
+ }
- return result;
- })
- .sort(function (a, b) {
- return a.score < b.score ? 1 : a.score === b.score ? 0 : -1;
- })[0] ||
+ result.score *= Math.pow(PENALTY_SKIPPED, split.before.length);
+ result.html = $('<div>').text(split.before).append($('<b>').text(split.chr)).append(result.html).html();
+
+ return result;
+ })
+ .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!
{
score: 0, // This 0 will multiply up to the top, giving a total of 0
html: $('<div>').text(string).html()
};
+
+ return $.extend({}, cache[string][abbreviation]);
};
/*global jQuery */
}(jQuery));
Please sign in to comment.
Something went wrong with that request. Please try again.