UNPKG

string-metric

Version:

Get string similarity in JavaScript or TypeScript

98 lines (97 loc) 3.19 kB
"use strict"; 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;