Sha256: eb89a2a796bf3f083fb63a0fdc0cd4ee5a66d2c6701b6a356547ca4ed157055e

Contents?: true

Size: 1.39 KB

Versions: 2

Compression:

Stored size: 1.39 KB

Contents

# -*- frozen-string-literal: true -*-

require "did_you_mean/levenshtein"
require "did_you_mean/jaro_winkler"

module DidYouMean
  module SpellCheckable
    def corrections
      @corrections ||= candidates.flat_map do |input, candidates|
        input     = normalize(input)
        threshold = input.length > 3 ? 0.834 : 0.77

        seed = candidates.select {|candidate| JaroWinkler.distance(normalize(candidate), input) >= threshold }
          .sort_by! {|candidate| JaroWinkler.distance(candidate.to_s, input) }
          .reverse!

        # Correct mistypes
        threshold   = (input.length * 0.25).ceil
        corrections = seed.select {|c| Levenshtein.distance(normalize(c), input) <= threshold }

        # Correct misspells
        if corrections.empty?
          corrections = seed.select do |candidate|
            candidate = normalize(candidate)
            length    = input.length < candidate.length ? input.length : candidate.length

            Levenshtein.distance(candidate, input) < length
          end.first(1)
        end

        corrections
      end
    end

    def candidates
      raise NotImplementedError
    end

    private

    def normalize(str_or_symbol) #:nodoc:
      str = if str_or_symbol.is_a?(String)
              str_or_symbol.dup
            else
              str_or_symbol.to_s
            end

      str.downcase!
      str.tr!("@", "")
      str
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
did_you_mean-1.0.0.rc1 lib/did_you_mean/spell_checkable.rb
did_you_mean-1.0.0.beta3 lib/did_you_mean/spell_checkable.rb