aboutsummaryrefslogtreecommitdiffstats
path: root/railties/lib/rails/command/spellchecker.rb
diff options
context:
space:
mode:
authorGenadi Samokovarov <gsamokovarov@gmail.com>2018-02-27 17:06:33 +0200
committerGenadi Samokovarov <gsamokovarov@gmail.com>2018-03-04 17:50:37 +0200
commita951729f45c579aa17b76a73f72880f90df9e910 (patch)
tree3be25fd52a520322cbe0491b60a85523decc6a0e /railties/lib/rails/command/spellchecker.rb
parent5af643d8d6f8af19a85a34475f40ac18db7c71e9 (diff)
downloadrails-a951729f45c579aa17b76a73f72880f90df9e910.tar.gz
rails-a951729f45c579aa17b76a73f72880f90df9e910.tar.bz2
rails-a951729f45c579aa17b76a73f72880f90df9e910.zip
Extract Rails::Command::Spellchecker
Diffstat (limited to 'railties/lib/rails/command/spellchecker.rb')
-rw-r--r--railties/lib/rails/command/spellchecker.rb53
1 files changed, 53 insertions, 0 deletions
diff --git a/railties/lib/rails/command/spellchecker.rb b/railties/lib/rails/command/spellchecker.rb
new file mode 100644
index 0000000000..59ccab4ea2
--- /dev/null
+++ b/railties/lib/rails/command/spellchecker.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+module Rails
+ module Command
+ module Spellchecker # :nodoc:
+ class << self
+ def suggest(word, from:, count: 3)
+ from.sort_by { |w| levenshtein_distance(word, w) }.take(count)
+ end
+
+ private
+ # This code is based directly on the Text gem implementation.
+ # Copyright (c) 2006-2013 Paul Battley, Michael Neumann, Tim Fletcher.
+ #
+ # Returns a value representing the "cost" of transforming str1 into str2.
+ def levenshtein_distance(str1, str2) # :doc:
+ s = str1
+ t = str2
+ n = s.length
+ m = t.length
+
+ return m if (0 == n)
+ return n if (0 == m)
+
+ d = (0..m).to_a
+ x = nil
+
+ # avoid duplicating an enumerable object in the loop
+ str2_codepoint_enumerable = str2.each_codepoint
+
+ str1.each_codepoint.with_index do |char1, i|
+ e = i + 1
+
+ str2_codepoint_enumerable.with_index do |char2, j|
+ cost = (char1 == char2) ? 0 : 1
+ x = [
+ d[j + 1] + 1, # insertion
+ e + 1, # deletion
+ d[j] + cost # substitution
+ ].min
+ d[j] = e
+ e = x
+ end
+
+ d[m] = x
+ end
+
+ x
+ end
+ end
+ end
+ end
+end