Module: Synthra::Utils::StringDistance
- Defined in:
- lib/synthra/utils/string_distance.rb
Overview
String distance calculations for "did you mean" suggestions
Provides methods to calculate edit distance between strings and find similar strings from a collection.
Class Method Summary collapse
-
.format_suggestions(suggestions) ⇒ String?
Format "did you mean" suggestion text.
-
.levenshtein(str1, str2) ⇒ Integer
Calculate Levenshtein distance between two strings.
-
.similar_strings(target, candidates, max_distance: 3, limit: 3) ⇒ Array<String>
Find strings similar to a target from a collection.
Class Method Details
.format_suggestions(suggestions) ⇒ String?
Format "did you mean" suggestion text
124 125 126 127 128 |
# File 'lib/synthra/utils/string_distance.rb', line 124 def format_suggestions(suggestions) return nil if suggestions.nil? || suggestions.empty? "Did you mean: #{suggestions.join(", ")}?" end |
.levenshtein(str1, str2) ⇒ Integer
Calculate Levenshtein distance between two strings
The Levenshtein distance is the minimum number of single-character edits (insertions, deletions, or substitutions) required to transform one string into another.
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 75 76 77 78 79 80 81 |
# File 'lib/synthra/utils/string_distance.rb', line 49 def levenshtein(str1, str2) str1 = str1.to_s.downcase str2 = str2.to_s.downcase return str2.length if str1.empty? return str1.length if str2.empty? return 0 if str1 == str2 # Create matrix m = str1.length n = str2.length d = Array.new(m + 1) { Array.new(n + 1) } # Initialize first column (0..m).each { |i| d[i][0] = i } # Initialize first row (0..n).each { |j| d[0][j] = j } # Fill in the rest of the matrix (1..m).each do |i| (1..n).each do |j| cost = str1[i - 1] == str2[j - 1] ? 0 : 1 d[i][j] = [ d[i - 1][j] + 1, # deletion d[i][j - 1] + 1, # insertion d[i - 1][j - 1] + cost # substitution ].min end end d[m][n] end |
.similar_strings(target, candidates, max_distance: 3, limit: 3) ⇒ Array<String>
Find strings similar to a target from a collection
Returns strings that are within the specified edit distance of the target, sorted by distance (closest first).
101 102 103 104 105 106 107 108 109 110 |
# File 'lib/synthra/utils/string_distance.rb', line 101 def similar_strings(target, candidates, max_distance: 3, limit: 3) target = target.to_s candidates .map { |c| [c, levenshtein(target, c)] } .select { |_, dist| dist <= max_distance } .sort_by { |_, dist| dist } .first(limit) .map(&:first) end |