module Eco module Data module FuzzyMatch class Results < Struct.new(:needle, :value, :raw_results) include Enumerable attr_accessor :threshold def empty? count < 1 end def each(&block) return to_enum(:each) unless block raw_results.each(&block) end # Merges the results of both Results object def merge(res) unless self.needle == res.needle raise "To merge 2 Results, needle should be the same ('#{value}'). Given '#{res.value}'" end self.class.new(needle, value, raw_results.concat(res.raw_results)) end def results_with_false_positives relevant_results(order: :jaro_winkler, threshold: 0.5) end def relevant_results(**options) options = {order: order, threshold: threshold || 0.5}.merge(options) raw_results.select do |result| result.all_threshold?(options[:order], options[:threshold]) end.yield_self do |filtered| self.class.new(needle, value, filtered).tap do |results| results.order = options[:order] end end end # @param values[Array] the algorithms' results it should be ordered by # * Possible values: `:dice`, `:levenshtein`, `:jaro_winkler`, `:ngrams`, `:words_ngrams`, `:chars_position`, `:average` def order=(values) @order = [values].flatten.compact.tap do |o| raw_results.each {|r| r.order = o} end end def order @order ||= [:words_ngrams, :dice] end def results raw_results.sort end def print msg = results.map do |result| result.print end.join("\n ") puts "'#{value}':\n " + msg end private def item_string(item, attr = self.method) return item if !item || item.is_a?(String) || !attr attr = attr.to_sym return item.send(attr) if item.respond_to?(attr) end end end end end