modular_tree 0.3.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a7ec15f5d6c64bba85a09321d1fcb7c1a22cd91fea24b1db49a2217a4dc73f08
4
- data.tar.gz: '08cf720767c7c907e3b7d8007125fafe5a8b51abe8701d4d0a0c5d5736df5ccd'
3
+ metadata.gz: '0900ab1e0482487fcb6b63c28fccb0d7dc7f71e5ce54230f3ee551ff67f0dfb5'
4
+ data.tar.gz: bf6b30a19df1fa8211b355bf06392dbefad2950a2a52bd494dad99605f392669
5
5
  SHA512:
6
- metadata.gz: 171988f0d2150f15a555d035fa7833e53b64784fcbbf3a4d5c3c4dc7ab352ce3aa816dee8a281c802bb236f57951112e0c1b18e451ad62b001e26f66340c3beb
7
- data.tar.gz: 23cefa409742a9926b83fb9f1f7aecdae78b78905d7ed765c1f4fdc0044730594d1ffda4ef806c513856b75ac40ba4d788f16c13312521d333d9a73ec0be036f
6
+ metadata.gz: 52d2ea9f3c82c6e7578f50b51804c223d267b1757f0709776addf39752e1034a57b14354f6877236d12017f2368300c5f3064537a3592f2fcf72bd69e2f991de
7
+ data.tar.gz: ad298843f7e45b03654ef53b96c507cf51ee0219c01abc4f30619a9396b17c9e775b64fb10b4fa9d3a9bbce0232f7235e2de2e283632a1cba38690634b9c909b
@@ -77,6 +77,21 @@ module Tree
77
77
  end
78
78
  end
79
79
 
80
+ # Filter children. Doesn't recurse. If a block is given, it should return
81
+ # truish to select a child node
82
+ #
83
+ # TODO: Maybe make #children an Array extended with filtering
84
+ def choose(match_expr = nil, &block)
85
+ matcher = Matcher.new(match_expr, &block)
86
+ if block_given?
87
+ a = []
88
+ each_branch { |branch, key| a << branch if matcher.match? branch }
89
+ a
90
+ else
91
+ Enumerator.new { |enum| each_branch { |branch, key| enum << branch if matcher.match? branch } }
92
+ end
93
+ end
94
+
80
95
  # Like #each but the block is called with node, key, and parent instead of
81
96
  # value, key, and parent
82
97
  def nodes(*filter, this: true, &block) = common_each(*filter, :node, :do_each_preorder, this, &block)
@@ -89,9 +104,8 @@ module Tree
89
104
 
90
105
  # Enumerator of edges in the tree. Edges are [previous-matching-node,
91
106
  # matching-node] tuples. Top-level nodes have previous-matching-node set to
92
- # nil
93
- #
94
- # FIXME: Not working right now. Not sure how #edges relates to #pairs
107
+ # nil. If the filter matches all nodes the value is an edge-representation
108
+ # of the tree
95
109
  def edges(*filter, this: true, &block)
96
110
  if block_given?
97
111
  each(*filter, this: this) { |node, _, parent| yield parent, node }
@@ -100,6 +114,19 @@ module Tree
100
114
  end
101
115
  end
102
116
 
117
+ # Return array of [previous-matching-node, matching-node] tuples. Returns
118
+ # the empty array ff there is no matching set of nodes
119
+ def pairs(first_match_expr, second_match_expr, this: true)
120
+ first_matcher = Matcher.new(first_match_expr)
121
+ second_matcher = Matcher.new(second_match_expr)
122
+ or_matcher = first_matcher | second_matcher # avoids re-computing this value over and over
123
+ result = []
124
+ nodes(first_matcher, false, this: this) { |node|
125
+ node.do_pairs(result, first_matcher, or_matcher)
126
+ }
127
+ result
128
+ end
129
+
103
130
  # Find nodes matching +filter+ and call +traverse_block+ with a node and a
104
131
  # block argument. +traverse_block+ can recurse into children by calling the
105
132
  # supplied inner block
@@ -117,18 +144,6 @@ module Tree
117
144
  nodes(filter, this: this).map { |node| traverse_block.call(node, inner_block) }
118
145
  end
119
146
 
120
- # Return array of [previous-matching-node, matching-node] tuples
121
- def pairs(first_matcher_expr, second_matcher_expr, this: true)
122
- first_matcher = Matcher.new(first_matcher_expr)
123
- second_matcher = Matcher.new(second_matcher_expr)
124
- or_matcher = first_matcher | second_matcher # avoids re-computing this value over and over
125
- result = []
126
- nodes(first_matcher, false, this: this) { |node|
127
- node.do_pairs(result, first_matcher, or_matcher)
128
- }
129
- result
130
- end
131
-
132
147
  # Traverse the tree top-down while accumulating information in an
133
148
  # accumulator object. The block takes a [accumulator, node] tuple and is
134
149
  # responsible for adding itself to the accumulator. The return value from
@@ -22,7 +22,7 @@ module Tree
22
22
  #
23
23
  # when +traverse+ is
24
24
  # true Traverse always. This is the default
25
- # false Traverse only if select didn't match
25
+ # false Traverse only if select didn't match # TODO: Never traverse to be able to use filters on children
26
26
  # nil Expects +select+ to be a Proc object that returns a [select,
27
27
  # traverse] tuple of booleans
28
28
  #
@@ -33,7 +33,7 @@ module Tree
33
33
  # It is not an error if the method doesn't exists on the a given node but
34
34
  # the node is not selected/traversed. If the expression is a class or an
35
35
  # array of classes, a given node matches if it is an instance of one of the
36
- # classes or any subclass
36
+ # classes and their subclasses
37
37
  #
38
38
  # If a block is given, it is supposed to return a [select, traverse] tuple
39
39
  # of booleans
@@ -42,6 +42,7 @@ module Tree
42
42
  # enumerators that doesn't execute the filter unless the enumerator is
43
43
  # evaluated
44
44
  #
45
+ # TODO: Accept RegExp -> use to_s to match
45
46
  def initialize(select_expr = nil, traverse_expr = nil, &block)
46
47
  if select_expr.nil? && block_given?
47
48
  @matcher = block
@@ -164,6 +164,7 @@ module Tree
164
164
  end
165
165
 
166
166
  def each_child(&block) = @children.map(&block)
167
+
167
168
  def attach(child) = @children << child
168
169
  def detach(arg)
169
170
  key = arg.is_a?(Integer) ? arg : @children.index(arg)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Tree
4
- VERSION = "0.3.0"
4
+ VERSION = "0.5.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: modular_tree
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Claus Rasmussen