# File lib/perseus_match/cluster.rb, line 35 def initialize(phrases = [], pm_options = {}, list_options = {}) super() { |h, k| h[k] = [] } List.pair(phrases, pm_options, list_options) { |pm| add(pm) } end
# File lib/perseus_match/cluster.rb, line 41 def add(pm) self[pm.phrase] << pm end
# File lib/perseus_match/cluster.rb, line 89 def rank(options = {}) coeff = options[:coeff] sort(options) { |match| [match.target, match.similarity(coeff)] } end
# File lib/perseus_match/cluster.rb, line 84 def sort(options = {}) args = [:similarity, options.delete(:coeff), options] block_given? ? sort_by(*args) { |*a| yield(*a) } : sort_by(*args) end
# File lib/perseus_match/cluster.rb, line 47 def sort_by(attribute, *args) options = args.last.is_a?(Hash) ? args.pop : {} _ = map { |phrase, matches| res = {} matches = matches.sort_by { |match| res[match] = match.send(attribute, *args) } # premise: if any is, then all are (i.e., only first needs checking) numeric = res.any? { |_, r| break r.is_a?(Numeric) } # sort numeric results in reverse order matches.reverse! if numeric if threshold = options[:threshold] condition = numeric ? lambda { |match| res[match] < threshold } : lambda { |match| res[match] > threshold } matches.reject!(&condition) end if limit = options[:limit] matches.slice!(limit..-1) if matches.size > limit end # transform entries if so requested matches.map! { |match| yield(match) } if block_given? [phrase, matches] }.sort _ # rcov hack :-( end