depth tracking
This commit is contained in:
parent
0c0fff22bb
commit
a45b5119cb
@ -24,28 +24,28 @@ public extension MoleculeModelProtocol {
|
|||||||
public extension MoleculeModelProtocol {
|
public extension MoleculeModelProtocol {
|
||||||
|
|
||||||
// Base case. No additional children to traverse.
|
// Base case. No additional children to traverse.
|
||||||
func reduceDepthFirstTraverse<Result>(options: TreeTraversalOptions, initialResult: Result, nextPartialResult: (Result, MoleculeModelProtocol)->Result) -> Result {
|
func reduceDepthFirstTraverse<Result>(options: TreeTraversalOptions, depth: Int, initialResult: Result, nextPartialResult: (Result, MoleculeModelProtocol, Int)->Result) -> Result {
|
||||||
return nextPartialResult(initialResult, self)
|
return nextPartialResult(initialResult, self, depth)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Base case. No additional children to traverse.
|
// Base case. No additional children to traverse.
|
||||||
func depthFirstTraverse(options: TreeTraversalOptions, onVisit: (MoleculeModelProtocol)->Void) {
|
func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol)->Void) {
|
||||||
onVisit(self)
|
onVisit(depth, self)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public extension Array where Element == MoleculeModelProtocol {
|
public extension Array where Element == MoleculeModelProtocol {
|
||||||
|
|
||||||
func reduceDepthFirstTraverse<Result>(options: TreeTraversalOptions, initialResult: Result, nextPartialResult: (Result, MoleculeModelProtocol)->Result) -> Result {
|
func reduceDepthFirstTraverse<Result>(options: TreeTraversalOptions, depth: Int, initialResult: Result, nextPartialResult: (Result, MoleculeModelProtocol, Int)->Result) -> Result {
|
||||||
return reduce(initialResult) { (result, molecule) -> Result in
|
return reduce(initialResult) { (result, molecule) -> Result in
|
||||||
return molecule.reduceDepthFirstTraverse(options: options, initialResult: result, nextPartialResult: nextPartialResult)
|
return molecule.reduceDepthFirstTraverse(options: options, depth: depth, initialResult: result, nextPartialResult: nextPartialResult)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func depthFirstTraverse(options: TreeTraversalOptions, callback: (MoleculeModelProtocol)->Void) {
|
func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, callback: (Int, MoleculeModelProtocol)->Void) {
|
||||||
forEach { (molecule) in
|
forEach { (molecule) in
|
||||||
molecule.depthFirstTraverse(options: options, onVisit: callback)
|
molecule.depthFirstTraverse(options: options, depth: depth, onVisit: callback)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,38 +16,39 @@ public protocol ParentMoleculeModelProtocol: MoleculeModelProtocol {
|
|||||||
|
|
||||||
public extension ParentMoleculeModelProtocol {
|
public extension ParentMoleculeModelProtocol {
|
||||||
|
|
||||||
func reduceDepthFirstTraverse<Result>(options: TreeTraversalOptions, initialResult: Result, nextPartialResult: (Result, MoleculeModelProtocol) -> Result) -> Result {
|
func reduceDepthFirstTraverse<Result>(options: TreeTraversalOptions, depth: Int, initialResult: Result, nextPartialResult: (Result, MoleculeModelProtocol, Int) -> Result) -> Result {
|
||||||
var result = initialResult
|
var result = initialResult
|
||||||
if (options == .parentFirst) {
|
if (options == .parentFirst) {
|
||||||
result = nextPartialResult(result, self)
|
result = nextPartialResult(result, self, depth)
|
||||||
}
|
}
|
||||||
result = children.reduce(result) { (result, molecule) -> Result in
|
result = children.reduce(result) { (result, molecule) -> Result in
|
||||||
if let additionalParent = molecule as? ParentMoleculeModelProtocol {
|
if let additionalParent = molecule as? ParentMoleculeModelProtocol {
|
||||||
// Safety net to make sure the ParentMoleculeModelProtocol's method extension is called over the base MoleculeModelProtocol.
|
// Safety net to make sure the ParentMoleculeModelProtocol's method extension is called over the base MoleculeModelProtocol.
|
||||||
return additionalParent.reduceDepthFirstTraverse(options: options, initialResult: result, nextPartialResult: nextPartialResult)
|
return additionalParent.reduceDepthFirstTraverse(options: options, depth: depth + 1, initialResult: result, nextPartialResult: nextPartialResult)
|
||||||
}
|
}
|
||||||
return molecule.reduceDepthFirstTraverse(options: options, initialResult: result, nextPartialResult: nextPartialResult)
|
return molecule.reduceDepthFirstTraverse(options: options, depth: depth + 1, initialResult: result, nextPartialResult: nextPartialResult)
|
||||||
}
|
}
|
||||||
if (options == .childFirst) {
|
if (options == .childFirst) {
|
||||||
result = nextPartialResult(result, self)
|
result = nextPartialResult(result, self, depth)
|
||||||
}
|
}
|
||||||
// if options == .leafOnly don't call on self.
|
// if options == .leafOnly don't call on self.
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func depthFirstTraverse(options: TreeTraversalOptions, onVisit: (MoleculeModelProtocol)->Void) {
|
func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol)->Void) {
|
||||||
if (options == .parentFirst) {
|
if (options == .parentFirst) {
|
||||||
onVisit(self)
|
onVisit(depth, self)
|
||||||
}
|
}
|
||||||
children.forEach { (molecule) in
|
children.forEach { (molecule) in
|
||||||
if let additionalParent = molecule as? ParentMoleculeModelProtocol {
|
if let additionalParent = molecule as? ParentMoleculeModelProtocol {
|
||||||
// Safety net to make sure the ParentMoleculeModelProtocol's method extension is called over the base MoleculeModelProtocol.
|
// Safety net to make sure the ParentMoleculeModelProtocol's method extension is called over the base MoleculeModelProtocol.
|
||||||
additionalParent.depthFirstTraverse(options: options, onVisit: onVisit)
|
additionalParent.depthFirstTraverse(options: options, depth: depth + 1, onVisit: onVisit)
|
||||||
|
} else {
|
||||||
|
molecule.depthFirstTraverse(options: options, depth: depth + 1, onVisit: onVisit)
|
||||||
}
|
}
|
||||||
molecule.depthFirstTraverse(options: options, onVisit: onVisit)
|
|
||||||
}
|
}
|
||||||
if (options == .childFirst) {
|
if (options == .childFirst) {
|
||||||
onVisit(self)
|
onVisit(depth, self)
|
||||||
}
|
}
|
||||||
// if options == .leafOnly don't call on self.
|
// if options == .leafOnly don't call on self.
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,9 +17,9 @@ public protocol MoleculeTreeTraversalProtocol {
|
|||||||
|
|
||||||
// Future options -- Parent first depth first, leaves only.
|
// Future options -- Parent first depth first, leaves only.
|
||||||
|
|
||||||
func reduceDepthFirstTraverse<Result>(options: TreeTraversalOptions, initialResult: Result, nextPartialResult: (Result, MoleculeModelProtocol)->Result) -> Result
|
func reduceDepthFirstTraverse<Result>(options: TreeTraversalOptions, depth: Int, initialResult: Result, nextPartialResult: (Result, MoleculeModelProtocol, Int)->Result) -> Result
|
||||||
|
|
||||||
func depthFirstTraverse(options: TreeTraversalOptions, onVisit: (MoleculeModelProtocol)->Void)
|
func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol)->Void)
|
||||||
|
|
||||||
//func breadthFirstTraverse()
|
//func breadthFirstTraverse()
|
||||||
}
|
}
|
||||||
@ -31,19 +31,19 @@ public protocol MoleculeTreeTraversalProtocol {
|
|||||||
extension MoleculeTreeTraversalProtocol {
|
extension MoleculeTreeTraversalProtocol {
|
||||||
|
|
||||||
func countMolecules(options: TreeTraversalOptions = .parentFirst) -> Int {
|
func countMolecules(options: TreeTraversalOptions = .parentFirst) -> Int {
|
||||||
return reduceDepthFirstTraverse(options: options, initialResult: 0) { (accumulator, molecule) in
|
return reduceDepthFirstTraverse(options: options, depth: 0, initialResult: 0) { (accumulator, molecule, depth) in
|
||||||
return accumulator + 1
|
return accumulator + 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func printMolecules(options: TreeTraversalOptions = .parentFirst) {
|
func printMolecules(options: TreeTraversalOptions = .parentFirst) {
|
||||||
depthFirstTraverse(options: options) { (molecule) in
|
depthFirstTraverse(options: options, depth: 1) { (depth, molecule) in
|
||||||
print("\"\(molecule.moleculeName)\" [\(molecule)]")
|
print("\(String(repeating: ">>", count: depth)) \"\(molecule.moleculeName)\" [\(molecule)]")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func allMoleculesOfType<T>(options: TreeTraversalOptions = .parentFirst) -> [T] {
|
func allMoleculesOfType<T>(options: TreeTraversalOptions = .parentFirst) -> [T] {
|
||||||
return reduceDepthFirstTraverse(options: options, initialResult: []) { (accumulator, molecule) in
|
return reduceDepthFirstTraverse(options: options, depth: 0, initialResult: []) { (accumulator, molecule, depth) in
|
||||||
if let typedMolecule = molecule as? T {
|
if let typedMolecule = molecule as? T {
|
||||||
return accumulator + [typedMolecule]
|
return accumulator + [typedMolecule]
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user