jaro_winkler 1.3.7 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|