modular_tree 0.11.0 → 0.13.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: c0947ea53f44cfdfdf8c615c26217fc7bfd86b9fae98f6c234519ace576f911d
4
- data.tar.gz: 6dc9685845668b34db4724828f777e80d1e808557c1e8b63988f23a82fdccccf
3
+ metadata.gz: 2cd6d39620d1c665267716d2089f1c498a1d0dd4aef5fc4b2cba175590d483a8
4
+ data.tar.gz: 9f6f684e5433a04541761abb0a6379e18093c77fb2e3cd257ae7bba49ada19c1
5
5
  SHA512:
6
- metadata.gz: e18eeb61df2ec711d51501175409ce1b085dc86d01c65ae3863f9abf4c72ff2e051dfc070541652acfdc6515859a2b7e0cf9c11ea665c5d1f9146c83ad881701
7
- data.tar.gz: b7f8dfbd482c7c64dd8f52f52d17d2ad2b4e82ee5e0604adbc790aa576ade55c0e26456df207938656ef5314fd4601809797669c11a488ba89d861e020bee905
6
+ metadata.gz: 72e405f8c4e5dcf4111c964301b482743d2ccec4b644c196fc64f15fe5393f713eb7f2e675f6c6f48a694764b4b055196e18a1a53145bfb6e9af920a6991325a
7
+ data.tar.gz: 01da8646f20a98c4b4dc85ed7f79e67842a0c5f3836a28a6b1e171f723c861d154ba250bb70243027404daf108f61e09a07a4d2fbf800fcd4a3a3beb9c1d5bee
@@ -10,15 +10,20 @@ module Tree
10
10
  include BranchesProperty
11
11
 
12
12
  # Bottom-up
13
- def ancestors # TODO: rename #parents
13
+ def parents(*filter)
14
+ filter = Filter.new(*filter)
14
15
  curr = self
15
16
  a = []
16
- a.push curr.node while curr = curr.branch
17
+ while curr = curr.branch
18
+ select, continue = filter.match(curr.node)
19
+ a.push curr.node if select
20
+ break if !continue
21
+ end
17
22
  a
18
23
  end
19
24
 
20
25
  # Top-down # TODO: rename #ancestors
21
- def ancestry
26
+ def ancestors
22
27
  curr = self
23
28
  a = []
24
29
  a.unshift curr.node while curr = curr.branch
@@ -69,11 +74,18 @@ module Tree
69
74
 
70
75
  # Implementation of Enumerable#select extended with a single filter. As
71
76
  # #each, the block is called with value, key, and parent arguments
72
- def select(filter = nil, this: true, &block)
77
+ #
78
+ # The match expression can also be a list of classes (instead of an array of classes)
79
+ #
80
+ def select(*expr, this: true, &block)
81
+ !block_given? || expr.empty? or raise ArgumentError, "Can't use both match expression and block"
73
82
  if block_given?
74
- each(block, true, this: this).to_a
83
+ each.select { |branch| yield branch }
84
+ elsif !expr.empty?
85
+ matcher = Matcher.new(*expr, &block)
86
+ each.select { |branch| matcher.match? branch }
75
87
  else
76
- each(filter || true, true, this: this)
88
+ each
77
89
  end
78
90
  end
79
91
 
@@ -83,14 +95,15 @@ module Tree
83
95
  # The match expression can also be a list of classes (instead of an array of classes)
84
96
  #
85
97
  # TODO: Maybe make #children an Array extended with filtering
86
- def choose(*args, &block)
87
- matcher = Matcher.new(*args, &block)
98
+ def choose(*expr, &block)
99
+ !block_given? || expr.empty? or raise ArgumentError, "Can't use both match expression and block"
88
100
  if block_given?
89
- a = []
90
- each_branch { |branch, key| a << branch if matcher.match? branch }
91
- a
101
+ each_branch.select { |branch| yield branch }
102
+ elsif !expr.empty?
103
+ matcher = Matcher.new(*expr, &block)
104
+ each_branch.select { |branch| matcher.match? branch }
92
105
  else
93
- Enumerator.new { |enum| each_branch { |branch, key| enum << branch if matcher.match? branch } }
106
+ each
94
107
  end
95
108
  end
96
109
 
@@ -104,10 +117,14 @@ module Tree
104
117
  # Post-order enumerator of selected nodes
105
118
  def postorder(*filter, this: true) = common_each(*filter, :node_value, :each_postorder, this)
106
119
 
120
+ # TODO IDEA:
121
+ # edges -> parent/child nodes
122
+ # pairs -> parent/.../descendant nodes
123
+
107
124
  # Enumerator of edges in the tree. Edges are [previous-matching-node,
108
125
  # matching-node] tuples. Top-level nodes have previous-matching-node set to
109
- # nil. If the filter matches all nodes the value is an edge-representation
110
- # of the tree
126
+ # nil (the result is a forrest). If the filter matches all nodes the value
127
+ # is an edge-representation of the tree
111
128
  def edges(*filter, this: true, &block)
112
129
  if block_given?
113
130
  each(*filter, this: this) { |node, _, parent| yield parent, node }
@@ -117,7 +134,7 @@ module Tree
117
134
  end
118
135
 
119
136
  # Return array of [previous-matching-node, matching-node] tuples. Returns
120
- # the empty array ff there is no matching set of nodes
137
+ # the empty array iff there is no matching set of nodes
121
138
  def pairs(first_match_expr, second_match_expr, this: true)
122
139
  first_matcher = Matcher.new(first_match_expr)
123
140
  second_matcher = Matcher.new(second_match_expr)
@@ -159,6 +159,9 @@ module Tree
159
159
  attr_writer :next_sibling
160
160
  end
161
161
 
162
+ # TODO: A ChildrenArrayImplementation that defines #insert and #append and
163
+ # adds an optional index argument to #attach
164
+
162
165
  module InternalChildrenArrayImplementation
163
166
  include InternalChildrenImplementation
164
167
 
@@ -183,6 +186,8 @@ module Tree
183
186
  # index or an object
184
187
  #
185
188
  # TODO: Rename #attach. #insert & #append are Enumerable operations
189
+ #
190
+ # TODO: Default where argument - insert: 0, append: -1
186
191
  def insert(where, child) = insert_append(:insert, where, child)
187
192
  def append(where, child) = insert_append(:append, where, child)
188
193
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Tree
4
- VERSION = "0.11.0"
4
+ VERSION = "0.13.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: modular_tree
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.0
4
+ version: 0.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Claus Rasmussen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-12-23 00:00:00.000000000 Z
11
+ date: 2023-01-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: constrain