trie_matcher 1.1.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dddc71cc0d9fbd56692fecc169fa82a1c3210f05
4
- data.tar.gz: 5014bbd465269d7cf3ccd8d32d9271c29da4f2f3
3
+ metadata.gz: 6826addd0962f940a478110fdd7f434a47576822
4
+ data.tar.gz: cbc905b0ad75449a9b8fa06794b76b2bfe9b2d6f
5
5
  SHA512:
6
- metadata.gz: f1c04ca6e84899d4071dd2fc55b0842de91b089104505eff617c95c2936280e93d1fe625d279a45a48831e306d39dea1e05349c5bb234e20d3b109402e28bcda
7
- data.tar.gz: 7826761862533ccf710ac0bfbb8e09eb87b5a3dec208638d6db4fb94bff86afc8cf38337b8eeaf6ac14e85591b01a8f71932b0535f3d7812d92f3638efa2772c
6
+ metadata.gz: 81d3a5f4b73e38debef8881db1a3095c60adbb7b9bedcb3070281a1616419fb13e68198b13e970a74bbe4998126228dc5cd40ba12321307cf7359114746b1ac7
7
+ data.tar.gz: 05dba91f89e9d004ac456744e12a19263dd2951a56152e2d39556655723c36d165bd9ad5867c145f2cd0ab89bb417ccf1d2a97a011d3d4db045e346f7add3ee3
data/lib/trie_matcher.rb CHANGED
@@ -44,6 +44,39 @@ class TrieMatcher
44
44
  return previous[:value]
45
45
  end
46
46
 
47
+ # Perform a prefix search, and return all values in the trie that have this prefix
48
+ #
49
+ # @param prefix [String] the prefix to search the trie with
50
+ # @return [<Object>] the values that start with the given prefix
51
+ def match(prefix)
52
+ result = []
53
+ current = @root
54
+ current_prefix = prefix
55
+
56
+ while current != nil && current_prefix != ""
57
+ previous, previous_prefix = current, current_prefix
58
+ current, current_prefix = next_node(current, current_prefix)
59
+ end
60
+
61
+ unless current
62
+ if current_prefix
63
+ return []
64
+ else
65
+ next_nodes = previous[:nodes].select { |prefix, node| prefix.start_with?(previous_prefix) }.values
66
+ end
67
+ else
68
+ next_nodes = [current]
69
+ end
70
+
71
+ until next_nodes.empty?
72
+ current = next_nodes.pop
73
+ result << current[:value]
74
+ current[:nodes].each { |prefix, node| next_nodes.push(node) }
75
+ end
76
+
77
+ return result.compact
78
+ end
79
+
47
80
  private
48
81
  # get the node for insertion, splitting shared prefixes into subnodes if necessary
49
82
  def find_canididate_insertion_node(current, key)
@@ -1,3 +1,3 @@
1
1
  class TrieMatcher
2
- VERSION = "1.1.1"
2
+ VERSION = "1.2.0"
3
3
  end
@@ -1,70 +1,96 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe TrieMatcher do
4
+ before do
5
+ @t = TrieMatcher.new
6
+ end
7
+
4
8
  it 'has a version number' do
5
9
  expect(TrieMatcher::VERSION).not_to be nil
6
10
  end
7
11
 
8
12
  it 'should store values' do
9
- t = TrieMatcher.new
10
- t["foo"] = "bar"
13
+ @t["foo"] = "bar"
11
14
  end
12
15
 
13
16
  it 'should retrieve stored values' do
14
- t = TrieMatcher.new
15
17
  value = "bar"
16
- t["foo"] = value
17
- expect(t["foo"]).to be value
18
+ @t["foo"] = value
19
+ expect(@t["foo"]).to be value
18
20
  end
19
21
 
20
22
  it 'should return the stored value' do
21
- t = TrieMatcher.new
22
23
  value = "bar"
23
- expect(t["foo"] = value).to be value
24
+ expect(@t["foo"] = value).to be value
24
25
  end
25
26
 
26
27
  it 'should store values with shared prefixes' do
27
- t = TrieMatcher.new
28
- t["cat"] = 1
29
- t["car"] = 2
30
- expect(t["cat"]).to be 1
31
- expect(t["car"]).to be 2
28
+ @t["cat"] = 1
29
+ @t["car"] = 2
30
+ expect(@t["cat"]).to be 1
31
+ expect(@t["car"]).to be 2
32
32
  end
33
33
 
34
34
  it 'should store keys that are a prefix of other keys' do
35
- t = TrieMatcher.new
36
- t["catch"] = 1
37
- t["cat"] = 2
38
- expect(t["catch"]).to be 1
39
- expect(t["cat"]).to be 2
35
+ @t["catch"] = 1
36
+ @t["cat"] = 2
37
+ expect(@t["catch"]).to be 1
38
+ expect(@t["cat"]).to be 2
40
39
  end
41
40
 
42
41
  it 'should store keys that have a prefix of another key' do
43
- t = TrieMatcher.new
44
- t["cat"] = 1
45
- t["catch"] = 2
46
- expect(t["cat"]).to be 1
47
- expect(t["catch"]).to be 2
42
+ @t["cat"] = 1
43
+ @t["catch"] = 2
44
+ expect(@t["cat"]).to be 1
45
+ expect(@t["catch"]).to be 2
48
46
  end
49
47
 
50
48
  it 'should do prefix searching' do
51
- t = TrieMatcher.new
52
- t["cat"] = 1
53
- expect(t["cats"]).to be 1
49
+ @t["cat"] = 1
50
+ expect(@t["cats"]).to be 1
54
51
  end
55
52
 
56
53
  it 'should do partial prefix matching' do
57
- t = TrieMatcher.new
58
- t["cat"] = 1
59
- t["cats in the cradle"] = 2
60
- expect(t["cats"]).to be 1
54
+ @t["cat"] = 1
55
+ @t["cats in the cradle"] = 2
56
+ expect(@t["cats"]).to be 1
61
57
  end
62
58
 
63
59
  it 'should return the more specific prefix value' do
64
- t = TrieMatcher.new
65
- t["cat"] = 1
66
- t["catch"] = 2
67
- expect(t["catcher"]).to be 2
60
+ @t["cat"] = 1
61
+ @t["catch"] = 2
62
+ expect(@t["catcher"]).to be 2
63
+ end
64
+
65
+ it 'should not give a longer prefix value' do
66
+ @t["catch"] = 2
67
+ expect(@t["cat"]).to be nil
68
+ end
69
+
70
+ it 'should return all values that are a prefix' do
71
+ @t["cats"] = 1
72
+ @t["foobar"] = 2
73
+ @t["foobaz"] = 3
74
+ @t["foobars"] = 4
75
+ @t["food"] = 5
76
+
77
+ expect(@t.match("foo").sort).to eq [2,3,4,5]
78
+ end
79
+
80
+ it 'should return a single value when there is only one match' do
81
+ @t["cats"] = 1
82
+ @t["dogs"] = 2
83
+ @t["birds"] = 3
84
+ @t["bees"] = 4
85
+
86
+ expect(@t.match("dog")).to eq [2]
68
87
  end
69
88
 
89
+ it 'should return an empty result when there are no prefix matches' do
90
+ @t["cat"] = 1
91
+ @t["dog"] = 2
92
+ @t["catch"] = 3
93
+
94
+ expect(@t.match("catcher")).to eq []
95
+ end
70
96
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trie_matcher
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steven Karas
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-07 00:00:00.000000000 Z
11
+ date: 2015-08-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler