module Query # Combines tokens and category indexes into combinations. # class Combinator attr_reader :categories, :category_hash attr_reader :ignore_unassigned_tokens # TODO Should this actually be determined by the query? Probably, yes. def initialize categories, options = {} @categories = categories @category_hash = hashify categories @ignore_unassigned_tokens = options[:ignore_unassigned_tokens] || false end # TODO Move somewhere else. # # TODO Or use active_support's? # def hashify category_array category_array.inject({}) do |hash, category| hash[category.name] = [category] hash end end # # def possible_combinations_for token token.similar? ? similar_possible_for(token) : possible_for(token) end # TODO Break apart. # def similar_possible_for token # Get as many similar tokens as necessary # text = token.text tokens = categories.inject([]) do |result, category| next_token = token # TODO adjust either this or the amount of similar in index # while next_token = next_token.next(category) result << next_token if next_token && next_token.text != text end result end # possible combinations # tokens.inject([]) do |result, token| possible = possible_categories token result + possible_for(token, possible) end end # Returns possible Combinations for the token. # # The categories param is an optimization. # # TODO Return [RemovedCategory(token, nil)] # If the search is ... # # TODO Make categories also a collection class. # # TODO Return [] if not ok, nil if needs to be removed? # Somehow unnice, but… # def possible_for token, preselected_categories = nil possible = (preselected_categories || possible_categories(token)).map { |category| category.combination_for(token) } possible.compact! # This is an optimization to mark tokens that are ignored. # return if ignore_unassigned_tokens && possible.empty? possible # wrap in combinations end # # # TODO too many calls? # def possible_categories token user_defined_categories(token) || categories end # Returns nil if there is no user defined category, the category else. # def user_defined_categories token category_hash[token.user_defined_category_name] end end end