Skip to content

Commit 6244845

Browse files
authored
Merge pull request #336 from rubyworks/claude/github-connector-capabilities-4qcre6
Fix String#similarity to divide by the longer length.
2 parents 3d79004 + 7af6a1a commit 6244845

4 files changed

Lines changed: 18 additions & 5 deletions

File tree

‎HISTORY.md‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ Changes:
6262
quietly changed both.
6363
* `Enumerable::Argumentable#min` and `#max` now pass their arguments to
6464
`#each`, as documented, rather than to Ruby's own `min(n)`/`max(n)`.
65+
* `String#similarity` now divides the shared length by the longer string's
66+
length, not length + 1, so 9 of 10 matching characters score 0.9 as its
67+
docs said (it gave 0.818). Scores for non-identical strings rise slightly.
6568
* `require 'facets'` no longer crashes on Ruby 4.1, which removed
6669
`ObjectSpace._id2ref`. `ObjectSpace[]` is only defined where `_id2ref`
6770
exists.

‎demo/core/string/similarity.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
A fuzzy matching mechanism. Returns a score from 0-1, based on the number of
66
shared edges. To be effective, the strings must be of length 2 or greater.
77

8-
"Alexsander".similarity("Aleksander").round(2).assert == 0.82
8+
"Alexsander".similarity("Aleksander").assert == 0.9
99

1010
"Alexander".similarity("Alexander").assert == 1.0
1111

‎lib/core/facets/string/similarity.rb‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ class String
44
# on the number of shared edges. To be effective, the strings
55
# must be of length 2 or greater.
66
#
7-
# "Alexsander".similarity("Aleksander") #=> 0.8181818181818182
7+
# "Alexsander".similarity("Aleksander") #=> 0.9
88
#
99
# The way it works:
1010
#
@@ -82,8 +82,9 @@ def similarity(str_in)
8282

8383
score = 0.0
8484
matches.each{ |mm| score += mm.length }
85-
self.length > str_in.length ? largest = self.length : largest = str_in.length
86-
return score/(largest+1)
85+
largest = [self.length, str_in.length].max
86+
return 0.0 if largest.zero? # e.g. an empty Symbol or Array
87+
return score/largest
8788
end
8889

8990
end

‎test/core/string/test_similarity.rb‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
method :similarity do
66

77
test do
8-
"Alexsanders".similarity("Aleksander").assert == 0.75
8+
"Alexsanders".similarity("Aleksander").round(3).assert == 0.818
99
end
1010

1111
test do
@@ -16,6 +16,15 @@
1616
"Alexander".similarity("").assert == 0.0
1717
end
1818

19+
test "9 of 10 characters shared" do
20+
"Alexsander".similarity("Aleksander").assert == 0.9
21+
end
22+
23+
test "empty non-String argument" do
24+
"".similarity(:"").assert == 0.0
25+
"".similarity([]).assert == 0.0
26+
end
27+
1928
end
2029

2130
end

0 commit comments

Comments
 (0)