Skip to content

Commit 2b40e57

Browse files
author
Reed Es
committed
getChildren methods consolidated for consistency
1 parent e767cd7 commit 2b40e57

File tree

3 files changed

+139
-86
lines changed

3 files changed

+139
-86
lines changed

README.md

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ _SwiftSimpleTree_ is part of the [OpenAlloc](https://github.com/openalloc) famil
99
## SimpleTree
1010

1111
```swift
12-
let foo = SimpleTree<String>(value: "foo")
12+
let foo = SimpleTree(value: "foo")
1313
let bar = foo.addChild(for: "bar")
1414
let baz = bar.addChild(for: "baz")
1515

@@ -24,6 +24,10 @@ print(baz.getParentValues())
2424
print(foo.getChildValues())
2525

2626
=> ["bar", "baz"]
27+
28+
print(foo.getSelfAndChildValues())
29+
30+
=> ["foo", "bar", "baz"]
2731
```
2832

2933
## Types
@@ -34,6 +38,15 @@ Types scoped within `SimpleTree`:
3438

3539
- `typealias ValueSet = Set<T>` - a set of values, where `T` is your hashable type.
3640

41+
An enumeration is used for the `traversal` argument in the `getChildren()` methods:
42+
43+
```swift
44+
public enum Traversal {
45+
case depthFirst
46+
case breadthFirst
47+
}
48+
```
49+
3750
## Instance Methods
3851

3952
#### Tree Maintenance
@@ -44,15 +57,13 @@ Types scoped within `SimpleTree`:
4457

4558
#### Node Retrieval
4659

47-
- `func getChildren(excludeValues: ValueSet) -> [Node]`: Fetch the child nodes of the node. Optional list of values for children to be excluded, along with their progeny. Traversal is breadth-first.
60+
- `func getChildren(traversal: Traversal, maxDepth: UInt, excludeValues: ValueSet) -> [Node]`: Fetch the child nodes of the node. Optional list of values for children to be excluded, along with their progeny. Traversal is `.breadthFirst` by default. NOTE: breadth-first with `maxDepth` not yet supported.
4861

49-
- `func getChildren(maxDepth: Int, excludeValues: ValueSet) -> [Node]`: Fetch the child nodes of the node. Optional list of values for children to be excluded, along with their progeny. Traversal is depth-first.
62+
- `func getSelfAndChildren(traversal: Traversal, maxDepth: UInt, excludeValues: ValueSet) -> [Node]`: Fetch the node and its child nodes. Optional list of values for nodes to be excluded, along with their progeny. Traversal is `.breadthFirst` by default. Self is at the first level of depth, so `maxDepth: 0` returns `[]`. NOTE: breadth-first with `maxDepth` not yet supported.
5063

5164
- `func getParent(excludeValues: ValueSet) -> Node?`: Return the immediate parent node, if any. Optional list of parent values to be excluded. A match will cause this function to return nil.
5265

53-
- `func getParents(maxDepth: Int, excludeValues: ValueSet) -> [Node]`: Return the parent nodes, starting with immediate parent. Optional list of parent values to be excluded. A match will exclude further ancestors. Optional limit on depth.
54-
55-
- `func getSelfAndChildren(excludeValues: ValueSet) -> [Node]`: Fetch the node and its child nodes. Optional list of values for nodes to be excluded, along with their progeny. Traversal is breadth-first.
66+
- `func getParents(maxDepth: UInt, excludeValues: ValueSet) -> [Node]`: Return the parent nodes, starting with immediate parent. Optional list of parent values to be excluded. A match will exclude further ancestors. Optional limit on depth.
5667

5768
#### Node Search
5869

@@ -68,15 +79,14 @@ Types scoped within `SimpleTree`:
6879

6980
#### Value retrieval
7081

71-
- `func getChildValues(excludeValues: ValueSet) -> [T]`: Fetch the values of the child nodes. Optional list of values for children to be excluded, along with their progeny. Traversal is breadth-first.
82+
- `func getChildValues(traversal: Traversal, maxDepth: UInt, excludeValues: ValueSet) -> [T]`: Fetch the values of the child nodes. Optional list of values for children to be excluded, along with their progeny. Traversal is `.breadthFirst` by default. NOTE: breadth-first with `maxDepth` not yet supported.
7283

73-
- `func getChildValues(maxDepth: Int, excludeValues: ValueSet) -> [T]`: Fetch the values of the child nodes. Optional list of values for children to be excluded, along with their progeny. Traversal is depth-first.
84+
- `func getSelfAndChildValues(excludeValues: ValueSet) -> [T]`: Fetch values for the node and its child nodes. Includes value of current node. Optional list of values for nodes to be excluded, along with their progeny. Self is at the first level of depth, so `maxDepth: 0` returns `[]`. Traversal is breadth-first, by default. NOTE: breadth-first with `maxDepth` not yet supported.
7485

7586
- `func getParentValue(excludeValues: ValueSet) -> T?`: Return the value of the immediate parent node, if any. Optional list of parent values to be excluded. A match will cause this function to return nil.
7687

77-
- `func getParentValues(maxDepth: Int, excludeValues: ValueSet) -> [T]`: Return the values of the parent nodes, starting with immediate parent. Optional list of parent values to be excluded. A match will exclude further ancestors. Optional limit on depth.
88+
- `func getParentValues(maxDepth: UInt, excludeValues: ValueSet) -> [T]`: Return the values of the parent nodes, starting with immediate parent. Optional list of parent values to be excluded. A match will exclude further ancestors. Optional limit on depth.
7889

79-
- `func getSelfAndChildValues(excludeValues: ValueSet) -> [T]`: Fetch values for the node and its child nodes. Includes value of current node. Optional list of values for nodes to be excluded, along with their progeny. Traversal is breadth-first.
8090

8191
## See Also
8292

Sources/SimpleTree.swift

Lines changed: 53 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -51,19 +51,24 @@ extension SimpleTree {
5151

5252
extension SimpleTree {
5353

54+
public enum Traversal {
55+
case depthFirst
56+
case breadthFirst
57+
}
58+
5459
/// Return the parent nodes, starting with immediate parent.
5560
/// Optional list of parent values to be excluded. A match will exclude further ancestors.
5661
/// Optional limit on depth.
57-
public func getParents(maxDepth: Int = Int.max, excludeValues: ValueSet = ValueSet()) -> [Node] {
62+
public func getParents(maxDepth: UInt = UInt.max, excludeValues: ValueSet = ValueSet()) -> [Node] {
5863
guard maxDepth > 0 else { return [] }
5964
let iter = self.makeParentIterator()
6065
var depth = maxDepth
6166
var parents = [Node]()
6267
while let parentNode = iter.next() {
6368
if excludeValues.contains(parentNode.value) { break }
6469
parents.append(parentNode)
70+
if depth == 1 { break }
6571
depth -= 1
66-
if depth == 0 { break }
6772
}
6873
return parents
6974
}
@@ -76,39 +81,42 @@ extension SimpleTree {
7681

7782
/// Fetch the child nodes of the node.
7883
/// Optional list of values for children to be excluded, along with their progeny.
79-
/// Traversal is depth-first.
80-
public func getChildren(maxDepth: Int, excludeValues: ValueSet = ValueSet()) -> [Node] {
81-
guard maxDepth > 0 else { return [] }
84+
/// Traversal is breadth-first by default.
85+
/// NOTE: breadth-first with maxDepth not yet supported.
86+
public func getChildren(traversal: Traversal = .breadthFirst, maxDepth: UInt = UInt.max, excludeValues: ValueSet = ValueSet()) -> [Node] {
8287
var nodes = [Node]()
83-
for child in children {
84-
if excludeValues.contains(child.value) { continue }
85-
nodes.append(child)
86-
if maxDepth > 1 {
87-
nodes.append(contentsOf: child.getChildren(maxDepth: maxDepth - 1, excludeValues: excludeValues))
88+
switch traversal {
89+
case .depthFirst:
90+
if maxDepth > 0 {
91+
for child in children {
92+
if excludeValues.contains(child.value) { continue }
93+
nodes.append(child)
94+
if maxDepth > 1 {
95+
let _children = child.getChildren(traversal: .depthFirst, maxDepth: maxDepth - 1, excludeValues: excludeValues)
96+
nodes.append(contentsOf: _children)
97+
}
98+
}
99+
}
100+
case .breadthFirst:
101+
guard maxDepth == UInt.max else { fatalError("breadth-first with maxDepth not yet supported") }
102+
let iter = self.makeChildIterator(excludeValues: excludeValues)
103+
while let node = iter.next() {
104+
nodes.append(node)
88105
}
89-
}
90-
return nodes
91-
}
92-
93-
/// Fetch the child nodes of the node.
94-
/// Optional list of values for children to be excluded, along with their progeny.
95-
/// Traversal is breadth-first.
96-
public func getChildren(excludeValues: ValueSet = ValueSet()) -> [Node] {
97-
var nodes = [Node]()
98-
let iter = self.makeChildIterator(excludeValues: excludeValues)
99-
while let node = iter.next() {
100-
nodes.append(node)
101106
}
102107
return nodes
103108
}
104109

105110
/// Fetch the node and its child nodes.
106111
/// Optional list of values for nodes to be excluded, along with their progeny.
107-
/// Traversal is breadth-first.
108-
public func getSelfAndChildren(excludeValues: ValueSet = ValueSet()) -> [Node] {
109-
guard !excludeValues.contains(self.value) else { return [] }
112+
/// Traversal is breadth-first by default.
113+
/// Self is at the first level of depth, so maxDepth: 0 returns [].
114+
/// NOTE: breadth-first with maxDepth not yet supported.
115+
public func getSelfAndChildren(traversal: Traversal = .breadthFirst, maxDepth: UInt = UInt.max, excludeValues: ValueSet = ValueSet()) -> [Node] {
116+
guard !excludeValues.contains(self.value), maxDepth > 0 else { return [] }
110117
var nodes: [Node] = [self]
111-
nodes.append(contentsOf: getChildren(excludeValues: excludeValues))
118+
let netMaxDepth = maxDepth - (traversal == .depthFirst ? 1 : 0)
119+
nodes.append(contentsOf: getChildren(traversal: traversal, maxDepth: netMaxDepth, excludeValues: excludeValues))
112120
return nodes
113121
}
114122
}
@@ -195,10 +203,28 @@ extension SimpleTree {
195203

196204
extension SimpleTree {
197205

206+
/// Fetch the values of the child nodes.
207+
/// Optional list of values for children to be excluded, along with their progeny.
208+
/// Traversal is breadth-first by default.
209+
/// NOTE: breadth-first with maxDepth not yet supported.
210+
public func getChildValues(traversal: Traversal = .breadthFirst, maxDepth: UInt = UInt.max, excludeValues: ValueSet = ValueSet()) -> [T] {
211+
getChildren(traversal: traversal, maxDepth: maxDepth, excludeValues: excludeValues).map(\.value)
212+
}
213+
214+
/// Fetch values for the node and its child nodes.
215+
/// Includes value of current node.
216+
/// Optional list of values for nodes to be excluded, along with their progeny.
217+
/// Self is at the first level of depth, so maxDepth: 0 returns [].
218+
/// Traversal is breadth-first, by default.
219+
/// NOTE: breadth-first with maxDepth not yet supported.
220+
public func getSelfAndChildValues(traversal: Traversal = .breadthFirst, maxDepth: UInt = UInt.max, excludeValues: ValueSet = ValueSet()) -> [T] {
221+
getSelfAndChildren(traversal: traversal, maxDepth: maxDepth, excludeValues: excludeValues).map(\.value)
222+
}
223+
198224
/// Return the values of the parent nodes, starting with immediate parent.
199225
/// Optional list of parent values to be excluded. A match will exclude further ancestors.
200226
/// Optional limit on depth.
201-
public func getParentValues(maxDepth: Int = Int.max, excludeValues: ValueSet = ValueSet()) -> [T] {
227+
public func getParentValues(maxDepth: UInt = UInt.max, excludeValues: ValueSet = ValueSet()) -> [T] {
202228
getParents(maxDepth: maxDepth, excludeValues: excludeValues).map(\.value)
203229
}
204230

@@ -207,25 +233,4 @@ extension SimpleTree {
207233
public func getParentValue(excludeValues: ValueSet = ValueSet()) -> T? {
208234
getParent(excludeValues: excludeValues)?.value
209235
}
210-
211-
/// Fetch the values of the child nodes.
212-
/// Optional list of values for children to be excluded, along with their progeny.
213-
/// Traversal is depth-first.
214-
public func getChildValues(maxDepth: Int, excludeValues: ValueSet = ValueSet()) -> [T] {
215-
getChildren(maxDepth: maxDepth, excludeValues: excludeValues).map(\.value)
216-
}
217-
218-
/// Fetch the values of the child nodes.
219-
/// Optional list of values for children to be excluded, along with their progeny.
220-
/// Traversal is breadth-first.
221-
public func getChildValues(excludeValues: ValueSet = ValueSet()) -> [T] {
222-
getChildren(excludeValues: excludeValues).map(\.value)
223-
}
224-
225-
/// Fetch values for the node and its child nodes.
226-
/// Optional list of values for nodes to be excluded, along with their progeny.
227-
/// Traversal is breadth-first.
228-
public func getSelfAndChildValues(excludeValues: ValueSet = ValueSet()) -> [T] {
229-
getSelfAndChildren(excludeValues: excludeValues).map(\.value)
230-
}
231236
}

0 commit comments

Comments
 (0)