mirror of
https://github.com/OpenXE-org/OpenXE.git
synced 2024-12-25 14:10:28 +01:00
106 lines
2.6 KiB
JavaScript
106 lines
2.6 KiB
JavaScript
|
/*
|
||
|
* LiquidMetal, version: 0.1 (2009-02-05)
|
||
|
*
|
||
|
* A mimetic poly-alloy of Quicksilver's scoring algorithm, essentially
|
||
|
* LiquidMetal.
|
||
|
*
|
||
|
* For usage and examples, visit:
|
||
|
* http://github.com/rmm5t/liquidmetal
|
||
|
*
|
||
|
* Licensed under the MIT:
|
||
|
* http://www.opensource.org/licenses/mit-license.php
|
||
|
*
|
||
|
* Copyright (c) 2009, Ryan McGeary (ryanonjavascript -[at]- mcgeary [*dot*] org)
|
||
|
* Modified by the Horde Project to use compressibility.
|
||
|
*
|
||
|
* @category Horde
|
||
|
* @package Core
|
||
|
*/
|
||
|
var LiquidMetal = {
|
||
|
|
||
|
SCORE_NO_MATCH: 0.0,
|
||
|
SCORE_MATCH: 1.0,
|
||
|
SCORE_TRAILING: 0.8,
|
||
|
SCORE_TRAILING_BUT_STARTED: 0.9,
|
||
|
SCORE_BUFFER: 0.85,
|
||
|
|
||
|
score: function(str, abbr)
|
||
|
{
|
||
|
// Short circuits
|
||
|
if (abbr.length == 0) {
|
||
|
return this.SCORE_TRAILING;
|
||
|
}
|
||
|
if (abbr.length > str.length) {
|
||
|
return this.SCORE_NO_MATCH;
|
||
|
}
|
||
|
|
||
|
var scores = this.buildScoreArray(str, abbr),
|
||
|
sum = 0.0;
|
||
|
|
||
|
scores.each(function(i) {
|
||
|
sum += i;
|
||
|
});
|
||
|
|
||
|
return (sum / scores.size());
|
||
|
},
|
||
|
|
||
|
buildScoreArray: function(str, abbr)
|
||
|
{
|
||
|
var lastIndex = -1,
|
||
|
lower = str.toLowerCase(),
|
||
|
scores = new Array(str.length),
|
||
|
started = false;
|
||
|
|
||
|
abbr.toLowerCase().split("").each(function(c) {
|
||
|
var index = to = lower.indexOf(c, lastIndex + 1),
|
||
|
val = this.SCORE_BUFFER;
|
||
|
|
||
|
if (index < 0) {
|
||
|
return this.fillArray(scores, this.SCORE_NO_MATCH);
|
||
|
}
|
||
|
|
||
|
if (index == 0) {
|
||
|
started = true;
|
||
|
}
|
||
|
|
||
|
if (this.isNewWord(str, index)) {
|
||
|
scores[index - 1] = 1;
|
||
|
to = index - 1;
|
||
|
} else if (!this.isUpperCase(str, index)) {
|
||
|
val = this.SCORE_NO_MATCH;
|
||
|
}
|
||
|
|
||
|
this.fillArray(scores, val, lastIndex + 1, val);
|
||
|
|
||
|
scores[index] = this.SCORE_MATCH;
|
||
|
lastIndex = index;
|
||
|
}.bind(this));
|
||
|
|
||
|
this.fillArray(scores, started ? this.SCORE_TRAILING_BUT_STARTED : this.SCORE_TRAILING, lastIndex + 1);
|
||
|
|
||
|
return scores;
|
||
|
},
|
||
|
|
||
|
isUpperCase: function(str, index)
|
||
|
{
|
||
|
var c = str.charAt(index);
|
||
|
return ("A" <= c && c <= "Z");
|
||
|
},
|
||
|
|
||
|
isNewWord: function(str, index)
|
||
|
{
|
||
|
var c = str.charAt(index - 1);
|
||
|
return (c == " " || c == "\t");
|
||
|
},
|
||
|
|
||
|
fillArray: function(arr, value, from, to)
|
||
|
{
|
||
|
from = Math.max(from || 0, 0);
|
||
|
to = Math.min(to || arr.length, arr.length);
|
||
|
for (var i = from; i < to; ++i) {
|
||
|
arr[i] = value;
|
||
|
}
|
||
|
return arr;
|
||
|
}
|
||
|
};
|