mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	 59c8d50653
			
		
	
	
		59c8d50653
		
	
	
	
	
		
			
			* bin/*, lib/bundler/*, lib/bundler.rb, spec/bundler, man/*:
    Merge from latest stable branch of bundler/bundler repository and
    added workaround patches. I will backport them into upstream.
  * common.mk, defs/gmake.mk: Added `test-bundler` task for test suite
    of bundler.
  * tool/sync_default_gems.rb: Added sync task for bundler.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65509 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
		
	
			
		
			
				
	
	
		
			63 lines
		
	
	
	
		
			1.8 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			63 lines
		
	
	
	
		
			1.8 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
| # frozen_string_literal: true
 | |
| 
 | |
| module Bundler
 | |
|   class SimilarityDetector
 | |
|     SimilarityScore = Struct.new(:string, :distance)
 | |
| 
 | |
|     # initialize with an array of words to be matched against
 | |
|     def initialize(corpus)
 | |
|       @corpus = corpus
 | |
|     end
 | |
| 
 | |
|     # return an array of words similar to 'word' from the corpus
 | |
|     def similar_words(word, limit = 3)
 | |
|       words_by_similarity = @corpus.map {|w| SimilarityScore.new(w, levenshtein_distance(word, w)) }
 | |
|       words_by_similarity.select {|s| s.distance <= limit }.sort_by(&:distance).map(&:string)
 | |
|     end
 | |
| 
 | |
|     # return the result of 'similar_words', concatenated into a list
 | |
|     # (eg "a, b, or c")
 | |
|     def similar_word_list(word, limit = 3)
 | |
|       words = similar_words(word, limit)
 | |
|       if words.length == 1
 | |
|         words[0]
 | |
|       elsif words.length > 1
 | |
|         [words[0..-2].join(", "), words[-1]].join(" or ")
 | |
|       end
 | |
|     end
 | |
| 
 | |
|   protected
 | |
| 
 | |
|     # http://www.informit.com/articles/article.aspx?p=683059&seqNum=36
 | |
|     def levenshtein_distance(this, that, ins = 2, del = 2, sub = 1)
 | |
|       # ins, del, sub are weighted costs
 | |
|       return nil if this.nil?
 | |
|       return nil if that.nil?
 | |
|       dm = [] # distance matrix
 | |
| 
 | |
|       # Initialize first row values
 | |
|       dm[0] = (0..this.length).collect {|i| i * ins }
 | |
|       fill = [0] * (this.length - 1)
 | |
| 
 | |
|       # Initialize first column values
 | |
|       (1..that.length).each do |i|
 | |
|         dm[i] = [i * del, fill.flatten]
 | |
|       end
 | |
| 
 | |
|       # populate matrix
 | |
|       (1..that.length).each do |i|
 | |
|         (1..this.length).each do |j|
 | |
|           # critical comparison
 | |
|           dm[i][j] = [
 | |
|             dm[i - 1][j - 1] + (this[j - 1] == that[i - 1] ? 0 : sub),
 | |
|             dm[i][j - 1] + ins,
 | |
|             dm[i - 1][j] + del
 | |
|           ].min
 | |
|         end
 | |
|       end
 | |
| 
 | |
|       # The last value in matrix is the Levenshtein distance between the strings
 | |
|       dm[that.length][this.length]
 | |
|     end
 | |
|   end
 | |
| end
 |