diff --git a/string_score.js b/string_score.js index d66254b..f635e05 100644 --- a/string_score.js +++ b/string_score.js @@ -1,5 +1,5 @@ /*! - * string_score.js: String Scoring Algorithm 0.1.21 + * string_score.js: String Scoring Algorithm 0.1.22 * * http://joshaven.com/string_score * https://github.com/joshaven/string_score @@ -9,93 +9,96 @@ * MIT License: http://opensource.org/licenses/MIT * * Date: Tue Mar 1 2011 - * Updated: Wed Jun 18 2014 + * Updated: Tue Mar 10 2015 */ +/*jslint nomen:true, white:true, browser:true,devel:true */ + /** * Scores a string against another string. * 'Hello World'.score('he'); //=> 0.5931818181818181 * 'Hello World'.score('Hello'); //=> 0.7318181818181818 */ String.prototype.score = function (word, fuzziness) { - 'use strict'; - - // If the string is equal to the word, perfect match. - if (this === word) { return 1; } - - //if it's not a perfect match and is empty return 0 - if (word === "") { return 0; } - - var runningScore = 0, - charScore, - finalScore, - string = this, - lString = string.toLowerCase(), - strLength = string.length, - lWord = word.toLowerCase(), - wordLength = word.length, - idxOf, - startAt = 0, - fuzzies = 1, - fuzzyFactor, - i; - - // Cache fuzzyFactor for speed increase - if (fuzziness) fuzzyFactor = 1 - fuzziness; - - // Walk through word and add up scores. - // Code duplication occurs to prevent checking fuzziness inside for loop - if (fuzziness) { - for (i = 0; i < wordLength; ++i) { - - // Find next first case-insensitive match of a character. - idxOf = lString.indexOf(lWord[i], startAt); - - if (-1 === idxOf) { - fuzzies += fuzzyFactor; - continue; - } else if (startAt === idxOf) { - // Consecutive letter & start-of-string Bonus - charScore = 0.7; - } else { - charScore = 0.1; - - // Acronym Bonus - // Weighing Logic: Typing the first character of an acronym is as if you - // preceded it with two perfect character matches. - if (string[idxOf - 1] === ' ') charScore += 0.8; - } - - // Same case bonus. - if (string[idxOf] === word[i]) charScore += 0.1; - - // Update scores and startAt position for next round of indexOf - runningScore += charScore; - startAt = idxOf + 1; - } - } else { - for (i = 0; i < wordLength; ++i) { - idxOf = lString.indexOf(lWord[i], startAt); - if (-1 === idxOf) { - return 0; - } else if (startAt === idxOf) { - charScore = 0.7; - } else { - charScore = 0.1; - if (string[idxOf - 1] === ' ') charScore += 0.8; - } - if (string[idxOf] === word[i]) charScore += 0.1; - runningScore += charScore; - startAt = idxOf + 1; + 'use strict'; + + // If the string is equal to the word, perfect match. + if (this === word) { return 1; } + + //if it's not a perfect match and is empty return 0 + if (word === "") { return 0; } + + var runningScore = 0, + charScore, + finalScore, + string = this, + lString = string.toLowerCase(), + strLength = string.length, + lWord = word.toLowerCase(), + wordLength = word.length, + idxOf, + startAt = 0, + fuzzies = 1, + fuzzyFactor, + i; + + // Cache fuzzyFactor for speed increase + if (fuzziness) { fuzzyFactor = 1 - fuzziness; } + + // Walk through word and add up scores. + // Code duplication occurs to prevent checking fuzziness inside for loop + if (fuzziness) { + for (i = 0; i < wordLength; i+=1) { + + // Find next first case-insensitive match of a character. + idxOf = lString.indexOf(lWord[i], startAt); + + if (idxOf === -1) { + fuzzies += fuzzyFactor; + } else { + if (startAt === idxOf) { + // Consecutive letter & start-of-string Bonus + charScore = 0.7; + } else { + charScore = 0.1; + + // Acronym Bonus + // Weighing Logic: Typing the first character of an acronym is as if you + // preceded it with two perfect character matches. + if (string[idxOf - 1] === ' ') { charScore += 0.8; } } - } - // Reduce penalty for longer strings. - finalScore = 0.5 * (runningScore / strLength + runningScore / wordLength) / fuzzies; + // Same case bonus. + if (string[idxOf] === word[i]) { charScore += 0.1; } - if ((lWord[0] === lString[0]) && (finalScore < 0.85)) { - finalScore += 0.15; + // Update scores and startAt position for next round of indexOf + runningScore += charScore; + startAt = idxOf + 1; + } } + } else { + for (i = 0; i < wordLength; i+=1) { + idxOf = lString.indexOf(lWord[i], startAt); + if (-1 === idxOf) { return 0; } + + if (startAt === idxOf) { + charScore = 0.7; + } else { + charScore = 0.1; + if (string[idxOf - 1] === ' ') { charScore += 0.8; } + } + if (string[idxOf] === word[i]) { charScore += 0.1; } + runningScore += charScore; + startAt = idxOf + 1; + } + } + + // Reduce penalty for longer strings. + finalScore = 0.5 * (runningScore / strLength + runningScore / wordLength) / fuzzies; + + if ((lWord[0] === lString[0]) && (finalScore < 0.85)) { + finalScore += 0.15; + } - return finalScore; + return finalScore; }; diff --git a/string_score.min.js b/string_score.min.js index ab38fa4..9a58a17 100644 --- a/string_score.min.js +++ b/string_score.min.js @@ -1,3 +1,3 @@ -// String Scoring Algorithm 0.1.21 | (c) 2009-2014 Joshaven Potter +// String Scoring Algorithm 0.1.22 | (c) 2009-2015 Joshaven Potter // MIT License: http://opensource.org/licenses/MIT | https://github.com/joshaven/string_score -String.prototype.score=function(e,r){"use strict";if(this===e)return 1;if(""===e)return 0;var t,i,n,o,f,s=0,u=this,h=u.toLowerCase(),a=u.length,c=e.toLowerCase(),g=e.length,l=0,d=1;if(r&&(o=1-r),r)for(f=0;g>f;++f)n=h.indexOf(c[f],l),-1!==n?(l===n?t=.7:(t=.1," "===u[n-1]&&(t+=.8)),u[n]===e[f]&&(t+=.1),s+=t,l=n+1):d+=o;else for(f=0;g>f;++f){if(n=h.indexOf(c[f],l),-1===n)return 0;l===n?t=.7:(t=.1," "===u[n-1]&&(t+=.8)),u[n]===e[f]&&(t+=.1),s+=t,l=n+1}return i=.5*(s/a+s/g)/d,c[0]===h[0]&&.85>i&&(i+=.15),i}; +String.prototype.score=function(e,f){if(this===e)return 1;if(""===e)return 0;var d=0,a,g=this.toLowerCase(),n=this.length,h=e.toLowerCase(),k=e.length,b;a=0;var l=1,m,c;f&&(m=1-f);if(f)for(c=0;cd&&(d+=.15);return d};