Skip to content

Commit 790b53c

Browse files
committed
Support for 5 param signature in levenshtein
This fixes issue locutusjs#166 The implementation is direct port of PHP's source code (except for param handling)
1 parent c4cb97e commit 790b53c

File tree

1 file changed

+56
-36
lines changed

1 file changed

+56
-36
lines changed

functions/strings/levenshtein.js

Lines changed: 56 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,42 @@
1-
function levenshtein(s1, s2) {
1+
function levenshtein(s1, s2, cost_ins, cost_rep, cost_del) {
22
// discuss at: http://phpjs.org/functions/levenshtein/
33
// original by: Carlos R. L. Rodrigues (http://www.jsfromhell.com)
44
// bugfixed by: Onno Marsman
55
// revised by: Andrea Giammarchi (http://webreflection.blogspot.com)
66
// reimplemented by: Brett Zamir (http://brett-zamir.me)
77
// reimplemented by: Alexander M Beedie
8+
// reimplemented by: Rafał Kukawski
89
// example 1: levenshtein('Kevin van Zonneveld', 'Kevin van Sommeveld');
910
// returns 1: 3
11+
// example 2: levenshtein("carrrot", "carrots");
12+
// returns 2: 2
13+
// example 3: levenshtein("carrrot", "carrots", 2, 3, 4);
14+
// returns 3: 6
15+
16+
var LEVENSHTEIN_MAX_LENGTH = 255; // PHP limits the function to max 255 character-long strings
17+
18+
cost_ins = cost_ins == null ? 1 : +cost_ins;
19+
cost_rep = cost_rep == null ? 1 : +cost_rep;
20+
cost_del = cost_del == null ? 1 : +cost_del;
1021

1122
if (s1 == s2) {
1223
return 0;
1324
}
1425

15-
var s1_len = s1.length;
16-
var s2_len = s2.length;
17-
if (s1_len === 0) {
18-
return s2_len;
26+
var l1 = s1.length;
27+
var l2 = s2.length;
28+
29+
if (l1 === 0) {
30+
return l2 * cost_ins;
1931
}
20-
if (s2_len === 0) {
21-
return s1_len;
32+
if (l2 === 0) {
33+
return l1 * cost_del;
2234
}
35+
36+
// Enable the 3 lines below to set the same limits on string length as PHP does
37+
/*if (l1 > LEVENSHTEIN_MAX_LENGTH || l2 > LEVENSHTEIN_MAX_LENGTH) {
38+
return -1;
39+
}*/
2340

2441
// BEGIN STATIC
2542
var split = false;
@@ -35,38 +52,41 @@ function levenshtein(s1, s2) {
3552
s2 = s2.split('');
3653
}
3754

38-
var v0 = new Array(s1_len + 1);
39-
var v1 = new Array(s1_len + 1);
55+
var p1 = new Array(l2 + 1);
56+
var p2 = new Array(l2 + 1);
4057

41-
var s1_idx = 0,
42-
s2_idx = 0,
43-
cost = 0;
44-
for (s1_idx = 0; s1_idx < s1_len + 1; s1_idx++) {
45-
v0[s1_idx] = s1_idx;
58+
var i1, i2, c0, c1, c2, tmp;
59+
60+
for (i2 = 0; i2 <= l2; i2++) {
61+
p1[i2] = i2 * cost_ins;
4662
}
47-
var char_s1 = '',
48-
char_s2 = '';
49-
for (s2_idx = 1; s2_idx <= s2_len; s2_idx++) {
50-
v1[0] = s2_idx;
51-
char_s2 = s2[s2_idx - 1];
52-
53-
for (s1_idx = 0; s1_idx < s1_len; s1_idx++) {
54-
char_s1 = s1[s1_idx];
55-
cost = (char_s1 == char_s2) ? 0 : 1;
56-
var m_min = v0[s1_idx + 1] + 1;
57-
var b = v1[s1_idx] + 1;
58-
var c = v0[s1_idx] + cost;
59-
if (b < m_min) {
60-
m_min = b;
63+
64+
for (i1 = 0; i1 < l1 ; i1++) {
65+
p2[0] = p1[0] + cost_del;
66+
67+
for (i2 = 0; i2 < l2; i2++) {
68+
c0 = p1[i2] + ((s1[i1] == s2[i2]) ? 0 : cost_rep);
69+
c1 = p1[i2 + 1] + cost_del;
70+
71+
if (c1 < c0) {
72+
c0 = c1;
6173
}
62-
if (c < m_min) {
63-
m_min = c;
74+
75+
c2 = p2[i2] + cost_ins;
76+
77+
if (c2 < c0) {
78+
c0 = c2;
6479
}
65-
v1[s1_idx + 1] = m_min;
80+
81+
p2[i2 + 1] = c0;
6682
}
67-
var v_tmp = v0;
68-
v0 = v1;
69-
v1 = v_tmp;
83+
84+
tmp = p1;
85+
p1 = p2;
86+
p2 = tmp;
7087
}
71-
return v0[s1_len];
72-
}
88+
89+
c0 = p1[l2];
90+
91+
return c0;
92+
}

0 commit comments

Comments
 (0)