string-metric
Version:
Get string similarity in JavaScript or TypeScript
98 lines (97 loc) • 3.19 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.JaroWinkler = void 0;
var utils_1 = require("./utils/utils");
var JaroWinkler = /** @class */ (function () {
function JaroWinkler(threshold) {
this.DEFAULT_THRESHOLD = 0.7;
this.THREE = 3;
this.JW_COEF = 0.1;
this.threshold = threshold || this.DEFAULT_THRESHOLD;
}
JaroWinkler.prototype.similarity = function (s1, s2) {
if (utils_1.isNullOrUndefined(s1)) {
throw new Error('s1 must neither be null nor undefined');
}
if (utils_1.isNullOrUndefined(s2)) {
throw new Error('s2 must neither be null nor undefined');
}
if (s1 === s2) {
return 1;
}
var mtp = this.matches(s1, s2);
var m = mtp[0];
if (m === 0) {
return 0;
}
var j = ((m / s1.length + m / s2.length + (m - mtp[1]) / m)) / this.THREE;
var jw = j;
if (j > this.threshold) {
jw = j + Math.min(this.JW_COEF, 1.0 / mtp[this.THREE]) * mtp[2] * (1 - j);
}
return jw;
};
JaroWinkler.prototype.distance = function (s1, s2) {
return 1 - this.similarity(s1, s2);
};
JaroWinkler.prototype.matches = function (s1, s2) {
var max;
var min;
if (s1.length > s2.length) {
max = s1;
min = s2;
}
else {
max = s2;
min = s1;
}
var range = Math.max(Math.floor(max.length / 2) - 1, 0);
var matchIndexes = Array(min.length);
matchIndexes.fill(-1);
var matchFlags = Array(max.length);
var matches = 0;
for (var mi = 0; mi < min.length; mi++) {
var c1 = min[mi];
for (var xi = Math.max(mi - range, 0), xn = Math.min(mi + range + 1, max.length); xi < xn; xi++) {
if (!matchFlags[xi] && c1 === max[xi]) {
matchIndexes[mi] = xi;
matchFlags[xi] = true;
matches++;
break;
}
}
}
var ms1 = Array(matches);
var ms2 = Array(matches);
for (var i = 0, si = 0; i < min.length; i++) {
if (matchIndexes[i] !== -1) {
ms1[si] = min[i];
si++;
}
}
for (var i = 0, si = 0; i < max.length; i++) {
if (matchFlags[i]) {
ms2[si] = max[i];
si++;
}
}
var transpositions = 0;
for (var mi = 0; mi < ms1.length; mi++) {
if (ms1[mi] !== ms2[mi]) {
transpositions++;
}
}
var prefix = 0;
for (var mi = 0; mi < min.length; mi++) {
if (s1[mi] === s2[mi]) {
prefix++;
}
else {
break;
}
}
return [matches, Math.floor(transpositions / 2), prefix, max.length];
};
return JaroWinkler;
}());
exports.JaroWinkler = JaroWinkler;
;