jaro_winkler 1.3.7 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/jaro_winkler/extconf.rb +4 -4
- data/ext/jaro_winkler/jaro.c +45 -26
- data/ext/jaro_winkler/jaro.h +3 -1
- data/ext/jaro_winkler/jaro_winkler.c +25 -8
- data/lib/jaro_winkler.rb +8 -75
- data/lib/jaro_winkler/jaro_winkler_pure.rb +125 -0
- data/lib/jaro_winkler/version.rb +1 -1
- metadata +5 -47
- data/lib/jaro_winkler/fallback.rb +0 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fe11a8c8be8cadef3f1f14f847c40a0a8e41268f
|
4
|
+
data.tar.gz: f509aaa81627917a4cf1017884f43b60dcd5483b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 88fca6ab51c8a830de64e23b96f7efaaeeac01cd71735dd3820fc9e84e5de0027872014a8aef0278658d45455a7719a81601604929d17228fd6e8b6cb8fba919
|
7
|
+
data.tar.gz: ab7ee1020506ba6693e2b9878afddcb4a39bf7fb0be89b3958cfc5571f051b8295898cf050d517aa2c1951b23093517ce2d82d8d9c5544e816a4ac9e34c5bc6c
|
data/ext/jaro_winkler/extconf.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
unless RUBY_PLATFORM == 'java'
|
2
|
-
require
|
2
|
+
require 'mkmf'
|
3
3
|
$CFLAGS << ' -std=c99 '
|
4
|
-
create_makefile(
|
4
|
+
create_makefile('jaro_winkler/jaro_winkler_ext')
|
5
5
|
else
|
6
|
-
dummy_makefile = open(
|
6
|
+
dummy_makefile = open('Makefile', 'wb')
|
7
7
|
dummy_makefile.puts '.PHONY: install'
|
8
8
|
dummy_makefile.puts 'install:'
|
9
|
-
dummy_makefile.puts "\t" + '@echo "
|
9
|
+
dummy_makefile.puts "\t" + '@echo "C extension is not installed, fall back to pure Ruby version instead."'
|
10
10
|
dummy_makefile.close
|
11
11
|
end
|
data/ext/jaro_winkler/jaro.c
CHANGED
@@ -6,19 +6,47 @@
|
|
6
6
|
#include <stdlib.h>
|
7
7
|
#include <ctype.h>
|
8
8
|
|
9
|
-
|
9
|
+
#define SWAP(x, y) do{ __typeof__(x) SWAP = x; x = y; y = SWAP; }while(0)
|
10
|
+
|
11
|
+
double jaro_distance_from_codes(unsigned long long *codes1, int len1, unsigned long long *codes2, int len2, LibJaroOption *opt);
|
12
|
+
double jaro_winkler_distance_from_codes(unsigned long long *codes1, int len1, unsigned long long *codes2, int len2, LibJaroOption *opt);
|
13
|
+
|
14
|
+
double jaro_distance(char* short_str, int short_str_len, char* long_str, int long_str_len, LibJaroOption *opt){
|
10
15
|
if(!short_str_len || !long_str_len) return 0.0;
|
11
16
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
17
|
+
unsigned long long *short_codes, *long_codes;
|
18
|
+
int short_codes_len, long_codes_len;
|
19
|
+
string_to_codes(short_str, short_str_len, &short_codes, &short_codes_len);
|
20
|
+
string_to_codes(long_str, long_str_len, &long_codes, &long_codes_len);
|
21
|
+
|
22
|
+
double ret = jaro_distance_from_codes(short_codes, short_codes_len, long_codes, long_codes_len, opt);
|
23
|
+
|
24
|
+
free(short_codes); free(long_codes);
|
25
|
+
return ret;
|
26
|
+
}
|
27
|
+
|
28
|
+
double jaro_winkler_distance(char* short_str, int short_str_len, char* long_str, int long_str_len, LibJaroOption *opt){
|
29
|
+
if(!short_str_len || !long_str_len) return 0.0;
|
16
30
|
|
17
31
|
unsigned long long *short_codes, *long_codes;
|
18
32
|
int short_codes_len, long_codes_len;
|
19
33
|
string_to_codes(short_str, short_str_len, &short_codes, &short_codes_len);
|
20
34
|
string_to_codes(long_str, long_str_len, &long_codes, &long_codes_len);
|
21
35
|
|
36
|
+
double ret = jaro_winkler_distance_from_codes(short_codes, short_codes_len, long_codes, long_codes_len, opt);
|
37
|
+
|
38
|
+
free(short_codes); free(long_codes);
|
39
|
+
return ret;
|
40
|
+
}
|
41
|
+
|
42
|
+
double jaro_distance_from_codes(unsigned long long* short_codes, int short_codes_len, unsigned long long* long_codes, int long_codes_len, LibJaroOption *opt){
|
43
|
+
if(!short_codes_len || !long_codes_len) return 0.0;
|
44
|
+
|
45
|
+
if(short_codes_len > long_codes_len){
|
46
|
+
SWAP(short_codes, long_codes);
|
47
|
+
SWAP(short_codes_len, long_codes_len);
|
48
|
+
}
|
49
|
+
|
22
50
|
if(opt->ignore_case){
|
23
51
|
for(int i = 0; i < short_codes_len; i++) short_codes[i] = tolower(short_codes[i]);
|
24
52
|
for(int i = 0; i < long_codes_len; i++) long_codes[i] = tolower(long_codes[i]);
|
@@ -27,10 +55,10 @@ double jaro_winkler_distance(char* short_str, int short_str_len, char* long_str,
|
|
27
55
|
int window_size = long_codes_len/2 - 1;
|
28
56
|
if(window_size < 0) window_size = 0;
|
29
57
|
|
30
|
-
char short_codes_flag[
|
31
|
-
char long_codes_flag[
|
32
|
-
memset(short_codes_flag, 0,
|
33
|
-
memset(long_codes_flag, 0,
|
58
|
+
char short_codes_flag[short_codes_len];
|
59
|
+
char long_codes_flag[long_codes_len];
|
60
|
+
memset(short_codes_flag, 0, short_codes_len);
|
61
|
+
memset(long_codes_flag, 0, long_codes_len);
|
34
62
|
|
35
63
|
// count number of matching characters
|
36
64
|
int match_count = 0;
|
@@ -46,10 +74,8 @@ double jaro_winkler_distance(char* short_str, int short_str_len, char* long_str,
|
|
46
74
|
}
|
47
75
|
}
|
48
76
|
}
|
49
|
-
|
50
|
-
|
51
|
-
return 0.0;
|
52
|
-
}
|
77
|
+
|
78
|
+
if(!match_count) return 0.0;
|
53
79
|
|
54
80
|
// count number of transpositions
|
55
81
|
int transposition_count = 0, j = 0, k = 0;
|
@@ -77,27 +103,20 @@ double jaro_winkler_distance(char* short_str, int short_str_len, char* long_str,
|
|
77
103
|
break;
|
78
104
|
}
|
79
105
|
|
80
|
-
// jaro distance
|
81
|
-
double jaro_distance;
|
82
106
|
double m = (double)match_count;
|
83
107
|
double t = (double)(transposition_count/2);
|
84
108
|
if(opt->adj_table) m = similar_count/10.0 + m;
|
85
|
-
|
109
|
+
return (m/short_codes_len + m/long_codes_len + (m-t)/m) / 3;
|
110
|
+
}
|
86
111
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
}
|
92
|
-
if(jaro_distance < opt->threshold){
|
93
|
-
free(short_codes); free(long_codes);
|
94
|
-
return jaro_distance;
|
95
|
-
}
|
112
|
+
double jaro_winkler_distance_from_codes(unsigned long long* short_codes, int short_codes_len, unsigned long long* long_codes, int long_codes_len, LibJaroOption *opt){
|
113
|
+
double jaro_distance = jaro_distance_from_codes(short_codes, short_codes_len, long_codes, long_codes_len, opt);
|
114
|
+
|
115
|
+
if(jaro_distance < opt->threshold) return jaro_distance;
|
96
116
|
else{
|
97
117
|
int prefix = 0;
|
98
118
|
int max_4 = short_codes_len > 4 ? 4 : short_codes_len;
|
99
119
|
for(prefix = 0; prefix < max_4 && short_codes[prefix] == long_codes[prefix]; prefix++);
|
100
|
-
free(short_codes); free(long_codes);
|
101
120
|
return jaro_distance + prefix*opt->weight*(1-jaro_distance);
|
102
121
|
}
|
103
122
|
}
|
data/ext/jaro_winkler/jaro.h
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
#ifndef LIBJARO_JARO_H
|
2
2
|
#define LIBJARO_JARO_H
|
3
3
|
|
4
|
-
#define SWAP(x, y) do{ __typeof__(x) SWAP = x; x = y; y = SWAP; }while(0)
|
5
4
|
#define DEFAULT_WEIGHT 0.1
|
6
5
|
#define DEFAULT_THRESHOLD 0.7
|
7
6
|
|
@@ -10,6 +9,9 @@ typedef struct LibJaroOption{
|
|
10
9
|
char ignore_case, adj_table;
|
11
10
|
} LibJaroOption;
|
12
11
|
|
12
|
+
|
13
|
+
static const LibJaroOption DEFAULT_OPT = {.weight = DEFAULT_WEIGHT, .threshold = DEFAULT_THRESHOLD, .ignore_case = 0, .adj_table = 0};
|
14
|
+
double jaro_distance(char *str1, int len1, char *str2, int len2, LibJaroOption *opt);
|
13
15
|
double jaro_winkler_distance(char *str1, int len1, char *str2, int len2, LibJaroOption *opt);
|
14
16
|
|
15
17
|
#endif
|
@@ -1,28 +1,45 @@
|
|
1
1
|
#include "ruby.h"
|
2
2
|
#include "jaro.h"
|
3
3
|
|
4
|
-
VALUE rb_mJaroWinkler
|
5
|
-
|
4
|
+
VALUE rb_mJaroWinkler,
|
5
|
+
rb_eError,
|
6
|
+
rb_eInvalidWeightError;
|
6
7
|
|
7
|
-
|
8
|
+
VALUE rb_jaro_winkler_distance(int argc, VALUE *argv, VALUE self);
|
9
|
+
VALUE rb_jaro_distance(int argc, VALUE *argv, VALUE self);
|
10
|
+
VALUE distance(int argc, VALUE *argv, VALUE self, double (*distance_fn)(char *str1, int len1, char *str2, int len2, LibJaroOption *opt));
|
11
|
+
|
12
|
+
void Init_jaro_winkler_ext(void){
|
8
13
|
rb_mJaroWinkler = rb_define_module("JaroWinkler");
|
9
|
-
|
14
|
+
rb_eError = rb_define_class_under(rb_mJaroWinkler, "Error", rb_eRuntimeError);
|
15
|
+
rb_eInvalidWeightError = rb_define_class_under(rb_mJaroWinkler, "InvalidWeightError", rb_eError);
|
16
|
+
rb_define_module_function(rb_mJaroWinkler, "distance", rb_jaro_winkler_distance, -1);
|
17
|
+
rb_define_module_function(rb_mJaroWinkler, "jaro_distance", rb_jaro_distance, -1);
|
10
18
|
}
|
11
19
|
|
12
|
-
|
20
|
+
|
21
|
+
VALUE distance(int argc, VALUE *argv, VALUE self, double (*distance_fn)(char *str1, int len1, char *str2, int len2, LibJaroOption *opt)){
|
13
22
|
VALUE s1, s2, opt;
|
14
23
|
rb_scan_args(argc, argv, "2:", &s1, &s2, &opt);
|
15
|
-
LibJaroOption c_opt =
|
24
|
+
LibJaroOption c_opt = DEFAULT_OPT;
|
16
25
|
if(TYPE(opt) == T_HASH){
|
17
26
|
VALUE weight = rb_hash_aref(opt, ID2SYM(rb_intern("weight"))),
|
18
27
|
threshold = rb_hash_aref(opt, ID2SYM(rb_intern("threshold"))),
|
19
28
|
ignore_case = rb_hash_aref(opt, ID2SYM(rb_intern("ignore_case"))),
|
20
29
|
adj_table = rb_hash_aref(opt, ID2SYM(rb_intern("adj_table")));
|
21
30
|
if(!NIL_P(weight)) c_opt.weight = NUM2DBL(weight);
|
22
|
-
if(c_opt.weight > 0.25) rb_raise(
|
31
|
+
if(c_opt.weight > 0.25) rb_raise(rb_eInvalidWeightError, "Scaling factor should not exceed 0.25, otherwise the distance can become larger than 1.");
|
23
32
|
if(!NIL_P(threshold)) c_opt.threshold = NUM2DBL(threshold);
|
24
33
|
if(!NIL_P(ignore_case)) c_opt.ignore_case = (TYPE(ignore_case) == T_FALSE || NIL_P(ignore_case)) ? 0 : 1;
|
25
34
|
if(!NIL_P(adj_table)) c_opt.adj_table = (TYPE(adj_table) == T_FALSE || NIL_P(adj_table)) ? 0 : 1;
|
26
35
|
}
|
27
|
-
return rb_float_new(
|
36
|
+
return rb_float_new((*distance_fn)(StringValuePtr(s1), RSTRING_LEN(s1), StringValuePtr(s2), RSTRING_LEN(s2), &c_opt));
|
37
|
+
}
|
38
|
+
|
39
|
+
VALUE rb_jaro_distance(int argc, VALUE *argv, VALUE self){
|
40
|
+
return distance(argc, argv, self, jaro_distance);
|
41
|
+
}
|
42
|
+
|
43
|
+
VALUE rb_jaro_winkler_distance(int argc, VALUE *argv, VALUE self){
|
44
|
+
return distance(argc, argv, self, jaro_winkler_distance);
|
28
45
|
}
|
data/lib/jaro_winkler.rb
CHANGED
@@ -1,76 +1,9 @@
|
|
1
|
-
require 'jaro_winkler/
|
2
|
-
require 'jaro_winkler/adjusting_table'
|
3
|
-
require 'jaro_winkler/jaro_winkler.so' unless JaroWinkler.fallback?
|
4
|
-
module JaroWinkler
|
5
|
-
module_function
|
6
|
-
def jaro_distance s1, s2, options = {}
|
7
|
-
options[:adj_table]
|
8
|
-
length1, length2 = s1.length, s2.length
|
9
|
-
# Guarantee the length order
|
10
|
-
if s1.length > s2.length
|
11
|
-
s1, s2 = s2, s1
|
12
|
-
length1, length2 = length2, length1
|
13
|
-
end
|
14
|
-
window_size = (length2 / 2) - 1
|
15
|
-
window_size = 0 if window_size < 0
|
16
|
-
matches = 0.0
|
17
|
-
sim_matches = 0.0
|
18
|
-
transpositions = 0
|
19
|
-
previous_index = -1
|
20
|
-
max_index = length2 - 1
|
21
|
-
s1.chars.each_with_index do |c1, i|
|
22
|
-
left = i - window_size
|
23
|
-
right = i + window_size
|
24
|
-
left = 0 if left < 0
|
25
|
-
right = max_index if right > max_index
|
26
|
-
matched = false
|
27
|
-
sim_matched = false
|
28
|
-
found = false
|
29
|
-
s2[left..right].chars.each_with_index do |c2, j|
|
30
|
-
if c1 == c2
|
31
|
-
matched = true
|
32
|
-
s2_index = left + j
|
33
|
-
if !found && s2_index > previous_index
|
34
|
-
previous_index = s2_index
|
35
|
-
found = true
|
36
|
-
end
|
37
|
-
elsif options[:adj_table] && DEFAULT_ADJ_TABLE[c1][c2]
|
38
|
-
sim_matched = true
|
39
|
-
end
|
40
|
-
end
|
41
|
-
if matched
|
42
|
-
matches += 1
|
43
|
-
transpositions += 1 unless found
|
44
|
-
elsif sim_matched # not matched but similarly matched
|
45
|
-
sim_matches += 3
|
46
|
-
end
|
47
|
-
end
|
48
|
-
# Don't divide transpositions by 2 since it's been counted directly by above code.
|
49
|
-
similarity = matches
|
50
|
-
similarity += sim_matches / 10 if options[:adj_table]
|
51
|
-
matches == 0 ? 0 : (similarity / length1 + similarity / length2 + (matches - transpositions) / matches) / 3.0
|
52
|
-
end
|
1
|
+
require 'jaro_winkler/version'
|
53
2
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
max_length = [4, s1.length, s2.length].min
|
62
|
-
s1[0, max_length].chars.each_with_index do |c1, i|
|
63
|
-
c1 == s2[i] ? prefix += 1 : break
|
64
|
-
end
|
65
|
-
distance < threshold ? distance : distance + ((prefix * weight) * (1 - distance))
|
66
|
-
end
|
67
|
-
|
68
|
-
if JaroWinkler.fallback?
|
69
|
-
alias :distance :r_distance
|
70
|
-
alias :c_distance :r_distance
|
71
|
-
module_function :distance, :c_distance
|
72
|
-
else
|
73
|
-
alias :distance :c_distance
|
74
|
-
module_function :distance
|
75
|
-
end
|
76
|
-
end
|
3
|
+
case RUBY_PLATFORM
|
4
|
+
when 'java'
|
5
|
+
require 'jaro_winkler/jaro_winkler_pure'
|
6
|
+
else
|
7
|
+
require 'jaro_winkler/jaro_winkler_ext'
|
8
|
+
end
|
9
|
+
|
@@ -0,0 +1,125 @@
|
|
1
|
+
require 'jaro_winkler/adjusting_table'
|
2
|
+
module JaroWinkler
|
3
|
+
class Error < RuntimeError; end
|
4
|
+
class InvalidWeightError < Error; end
|
5
|
+
|
6
|
+
DEFAULT_WEIGHT = 0.1
|
7
|
+
DEFAULT_THRESHOLD = 0.7
|
8
|
+
DEFAULT_OPTIONS = {
|
9
|
+
jaro: {adj_table: false, ignore_case: false},
|
10
|
+
jaro_winkler: {weight: DEFAULT_WEIGHT, threshold: DEFAULT_THRESHOLD}
|
11
|
+
}
|
12
|
+
|
13
|
+
module_function
|
14
|
+
|
15
|
+
def distance str1, str2, options={}
|
16
|
+
_distance str1.codepoints.to_a, str2.codepoints.to_a, options
|
17
|
+
end
|
18
|
+
|
19
|
+
def jaro_distance str1, str2, options={}
|
20
|
+
_jaro_distance str1.codepoints.to_a, str2.codepoints.to_a, options
|
21
|
+
end
|
22
|
+
|
23
|
+
def _distance codes1, codes2, options={}
|
24
|
+
options = DEFAULT_OPTIONS[:jaro_winkler].merge options
|
25
|
+
raise InvalidWeightError if options[:weight] > 0.25
|
26
|
+
jaro_distance = _jaro_distance(codes1, codes2, options);
|
27
|
+
|
28
|
+
if jaro_distance < options[:threshold]
|
29
|
+
jaro_distance
|
30
|
+
else
|
31
|
+
codes1, codes2 = codes2, codes1 if codes1.length > codes2.length
|
32
|
+
len1, len2 = codes1.length, codes2.length
|
33
|
+
max_4 = len1 > 4 ? 4 : len1
|
34
|
+
prefix = 0
|
35
|
+
while prefix < max_4 && codes1[prefix] == codes2[prefix]
|
36
|
+
prefix += 1
|
37
|
+
end
|
38
|
+
jaro_distance + prefix * options[:weight] * (1 - jaro_distance)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def _jaro_distance codes1, codes2, options={}
|
43
|
+
options = DEFAULT_OPTIONS[:jaro].merge options
|
44
|
+
|
45
|
+
codes1, codes2 = codes2, codes1 if codes1.length > codes2.length
|
46
|
+
len1, len2 = codes1.length, codes2.length
|
47
|
+
return 0.0 if len1 == 0 || len2 == 0
|
48
|
+
|
49
|
+
if options[:ignore_case]
|
50
|
+
codes1.map!{ |c| c >= 97 && c <= 122 ? c -= 32 : c }
|
51
|
+
codes2.map!{ |c| c >= 97 && c <= 122 ? c -= 32 : c }
|
52
|
+
end
|
53
|
+
|
54
|
+
window = len2/2 - 1
|
55
|
+
window = 0 if(window < 0)
|
56
|
+
flags1, flags2 = 0, 0
|
57
|
+
|
58
|
+
# // count number of matching characters
|
59
|
+
match_count = 0;
|
60
|
+
i = 0
|
61
|
+
while i < len1
|
62
|
+
left = (i >= window) ? i - window : 0
|
63
|
+
right = (i + window <= len2 - 1) ? (i + window) : (len2 - 1)
|
64
|
+
right = len2 - 1 if right > len2 - 1
|
65
|
+
j = left
|
66
|
+
while j <= right
|
67
|
+
if flags2[j] == 0 && codes1[i] == codes2[j]
|
68
|
+
flags1 |= (1 << i)
|
69
|
+
flags2 |= (1 << j)
|
70
|
+
match_count += 1
|
71
|
+
break
|
72
|
+
end
|
73
|
+
j +=1
|
74
|
+
end
|
75
|
+
i += 1
|
76
|
+
end
|
77
|
+
|
78
|
+
return 0.0 if match_count == 0
|
79
|
+
|
80
|
+
# // count number of transpositions
|
81
|
+
transposition_count = j = k = 0
|
82
|
+
i = 0
|
83
|
+
while i < len1
|
84
|
+
if flags1[i] == 1
|
85
|
+
j = k
|
86
|
+
while j < len2
|
87
|
+
if flags2[j] == 1
|
88
|
+
k = j + 1;
|
89
|
+
break;
|
90
|
+
end
|
91
|
+
j += 1
|
92
|
+
end
|
93
|
+
transposition_count += 1 if codes1[i] != codes2[j]
|
94
|
+
end
|
95
|
+
i += 1
|
96
|
+
end
|
97
|
+
|
98
|
+
# // count similarities in nonmatched characters
|
99
|
+
similar_count = 0
|
100
|
+
if options[:adj_table] && len1 > match_count
|
101
|
+
i = 0
|
102
|
+
while i < len1
|
103
|
+
if flags1[i] == 0
|
104
|
+
j = 0
|
105
|
+
while j < len2
|
106
|
+
if flags2[j] == 0
|
107
|
+
if DEFAULT_ADJ_TABLE[codes1[i].chr(Encoding::UTF_8)][codes2[j].chr(Encoding::UTF_8)]
|
108
|
+
similar_count += 3
|
109
|
+
break
|
110
|
+
end
|
111
|
+
end
|
112
|
+
j += 1
|
113
|
+
end
|
114
|
+
end
|
115
|
+
i += 1
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
m = match_count.to_f
|
120
|
+
t = transposition_count/2
|
121
|
+
m = similar_count/10.0 + m if options[:adj_table]
|
122
|
+
(m/len1 + m/len2 + (m-t)/m) / 3
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
data/lib/jaro_winkler/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jaro_winkler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jian Weihang
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-12-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -53,49 +53,7 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - ">="
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - ">="
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: fuzzy-string-match
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - ">="
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - ">="
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: hotwater
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - ">="
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '0'
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - ">="
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '0'
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: amatch
|
56
|
+
name: minitest
|
99
57
|
requirement: !ruby/object:Gem::Requirement
|
100
58
|
requirements:
|
101
59
|
- - ">="
|
@@ -128,7 +86,7 @@ files:
|
|
128
86
|
- ext/jaro_winkler/murmur_hash2.c
|
129
87
|
- lib/jaro_winkler.rb
|
130
88
|
- lib/jaro_winkler/adjusting_table.rb
|
131
|
-
- lib/jaro_winkler/
|
89
|
+
- lib/jaro_winkler/jaro_winkler_pure.rb
|
132
90
|
- lib/jaro_winkler/version.rb
|
133
91
|
homepage: https://github.com/tonytonyjan/jaro_winkler
|
134
92
|
licenses:
|
@@ -150,7 +108,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
150
108
|
version: '0'
|
151
109
|
requirements: []
|
152
110
|
rubyforge_project:
|
153
|
-
rubygems_version: 2.
|
111
|
+
rubygems_version: 2.5.1
|
154
112
|
signing_key:
|
155
113
|
specification_version: 4
|
156
114
|
summary: Ruby & C implementation of Jaro-Winkler distance algorithm which both support
|