-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathresemblance.js
More file actions
74 lines (59 loc) · 1.77 KB
/
Copy pathresemblance.js
File metadata and controls
74 lines (59 loc) · 1.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
'use strict';
var stripDiacritics = require('diacritics').remove;
var levenshtein = require('fast-levenshtein').get;
var _ = require('lodash');
exports.getSimilar = getSimilar;
exports.compareObjects = compareObjects;
exports.compareStrings = compareStrings;
function getSimilar (obj, set, weights, threshold) {
var similar = [];
threshold = threshold || -1;
_.forEach(set, function forEach (setObj) {
var resemblance = compareObjects(obj, setObj, weights);
if (resemblance > threshold) {
similar.push({
resemblance: resemblance,
obj: _.cloneDeep(setObj)
});
}
});
// sort results so that best match is result[0]
return similar.sort(function descendingResemblance (a, b) {
return b.resemblance - a.resemblance;
});
}
function compareStrings (a, b) {
// test falsy values
a = a || '';
b = b || '';
// to string
a = JSON.stringify(a);
b = JSON.stringify(b);
// unify case
a = a.toLowerCase();
b = b.toLowerCase();
// remove diacritics
a = stripDiacritics(a);
b = stripDiacritics(b);
// remove non alphanumerical characters
a = a.replace(/[^\w]+/g, '');
b = b.replace(/[^\w]+/g, '');
// likeness
return 1 - (levenshtein(a, b) / Math.max(Math.max(a.length, b.length), 1));
}
function compareObjects (a, b, weights) {
var resemblance = 0;
var totalWeight = 0;
var propWeight, aPropValue, bPropValue;
_.forOwn(weights, function forOwn (weight, key) {
propWeight = _.isNumber(weight) ? weight : 0;
aPropValue = _.has(a, key) ? _.get(a, key) : '';
bPropValue = _.has(b, key) ? _.get(b, key) : '';
resemblance += compareStrings(aPropValue, bPropValue) * propWeight;
totalWeight += propWeight;
});
if (totalWeight === 0) {
return 1;
}
return resemblance / totalWeight;
}