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
- #count(*args) ⇒ Object
-
#filter(*sig) ⇒ Object
like retrieve, but will return any kind of node.
- #increment(sig, val = 1) ⇒ Object
- #reduce(sig, base = 0) ⇒ Object
-
#reducer(sig, base, &block) ⇒ Object
a = ht.reducer([:a, :b, :c], 0) {|acc, v| acc + v } a.
-
#retrieve(*sig) ⇒ Object
Given a signature array, attempt to retrieve matching leaf values.
-
#search(sig) ⇒ Object
Generic tree search method.
-
#set(sig, val) ⇒ Object
Follow or create the path specified by the signature and assign the value as a terminating leaf node.
- #sum(*args) ⇒ Object
- #traverse ⇒ Object
- #unique(*args) ⇒ Object
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")
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 |
#traverse ⇒ Object
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 |