Module: Squeeze::Traversable

Included in:
HashTree
Defined in:
lib/squeeze/traversable.rb

Overview

Tree classes including this module must supply these methods:

  • #create_path(path_signature)

  • #find(path_signature)

  • #children(node_matcher)

Instance Method Summary collapse

Instance Method Details

#count(*args) ⇒ Object



61
62
63
64
# File 'lib/squeeze/traversable.rb', line 61

def count(*args)
  args = args + [:_count]
  sum(*args)
end

#filter(*sig) ⇒ Object

like retrieve, but will return any kind of node



73
74
75
76
77
78
79
80
# File 'lib/squeeze/traversable.rb', line 73

def filter(*sig)
  results = []
  search(sig) do |node|
    results << node
    yield(node) if block_given?
  end
  results
end

#increment(sig, val = 1) ⇒ Object



28
29
30
31
32
33
34
35
36
37
# File 'lib/squeeze/traversable.rb', line 28

def increment(sig, val=1)
  val = yield if block_given?
  create_path(sig) do |node, key|
    if node.has_key?(key)
      node[key] = node[key] + val
    else
      node[key] = val
    end
  end
end

#reduce(sig, base = 0) ⇒ Object



21
22
23
24
25
26
# File 'lib/squeeze/traversable.rb', line 21

def reduce(sig, base=0)
  create_path(sig) do |node, key|
    node[key] = base unless node.has_key?(key)
    node[key] = yield node[key]
  end
end

#reducer(sig, base, &block) ⇒ Object

a = ht.reducer([:a, :b, :c], 0) {|acc, v| acc + v } a



42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/squeeze/traversable.rb', line 42

def reducer(sig, base, &block)
  p = nil
  create_path(sig) do |node, key|
    unless node.has_key?(key)
      node[key] = base
    end
    p = lambda do |newval|
      node[key] = block.call(node[key], newval)
    end
  end
  p
end

#retrieve(*sig) ⇒ Object

Given a signature array, attempt to retrieve matching leaf values.



83
84
85
86
87
88
89
90
# File 'lib/squeeze/traversable.rb', line 83

def retrieve(*sig)
  results = []
  search(sig) do |node|
    results << node unless node.respond_to?(:children)
    yield(node) if block_given?
  end
  results
end

#search(sig) ⇒ Object

Generic tree search method



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/squeeze/traversable.rb', line 93

def search(sig)
  current_nodes = [self]

  while !current_nodes.empty?
    next_nodes = []
    matcher = sig.shift
    if matcher
      current_nodes.each do |node|
        if node.respond_to?(:children)
          next_nodes += node.children(matcher)
        end
      end
    else
      current_nodes.each {|n| yield(n) }
    end
    current_nodes = next_nodes
  end
end

#set(sig, val) ⇒ Object

Follow or create the path specified by the signature and assign the value as a terminating leaf node.

h.set([:a, :b, :c], "This is a retrievable value")

Raises:

  • (ArgumentError)


14
15
16
17
18
19
# File 'lib/squeeze/traversable.rb', line 14

def set(sig, val)
  raise ArgumentError if sig.empty?
  create_path(sig) do |node, key|
    node[key] = val
  end
end

#sum(*args) ⇒ Object



55
56
57
58
59
# File 'lib/squeeze/traversable.rb', line 55

def sum(*args)
  out = 0
  retrieve(*args) { |v| out += v }
  out
end

#traverseObject



112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/squeeze/traversable.rb', line 112

def traverse
  current_nodes = [self]
  while !current_nodes.empty?
    next_nodes = []
    current_nodes.each do |node|
      if node.respond_to?(:children)
        next_nodes += node.children(true)
        yield(node)
      end
    end

    current_nodes = next_nodes
  end
end

#unique(*args) ⇒ Object



66
67
68
69
70
# File 'lib/squeeze/traversable.rb', line 66

def unique(*args)
  out = 0
  filter(*args) { |v| out += v.size }
  out
end