Class: TuiTui::Fuzzy

Inherits:
Object
  • Object
show all
Defined in:
lib/tui_tui/fuzzy.rb

Overview

Query-prepared subsequence matcher used to rank many candidates consistently.

Defined Under Namespace

Classes: Match

Constant Summary collapse

BOUNDARY =
"/\\_-. ".freeze

Instance Method Summary collapse

Constructor Details

#initialize(query) ⇒ Fuzzy

Returns a new instance of Fuzzy.



10
11
12
# File 'lib/tui_tui/fuzzy.rb', line 10

def initialize(query)
  @query = query.to_s.downcase.grapheme_clusters
end

Instance Method Details

#match(string) ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/tui_tui/fuzzy.rb', line 14

def match(string)
  return Match.new(score: 0, positions: []) if @query.empty?

  haystack = string.downcase.grapheme_clusters
  positions = []
  from = 0
  @query.each do |grapheme|
    at = (from...haystack.size).find { |i| haystack[i] == grapheme } or return nil

    positions << at
    from = at + 1
  end

  Match.new(score: score(haystack, positions), positions: positions)
end

#rank(candidates) ⇒ Object



30
31
32
33
34
35
36
37
# File 'lib/tui_tui/fuzzy.rb', line 30

def rank(candidates)
  candidates
    .filter_map do |item|
      found = match(block_given? ? yield(item) : item)
      [item, found] if found
    end
    .sort_by { |(_item, found)| -found.score }
end