不要なパスをたどることなく、個別のノードを生成するリアクティブ DFS 実装を開発しようとしています。ツリーには、重複/等しいノードが含まれる場合があります。ノードがトラバースされた場合、そのすべての子もトラバースされているため、ノードに再び遭遇した場合、トラバーサルの拡張を停止できます。
class Traversal {
//exposed method with understandable signature
public IObservable<Node> DepthFirst(Node root) {
return DepthFirstRecursive(root, new List<Node>(), new SomeStatefulHelper());
}
//hidden method with accumulator for cutting
private IObservable<Node> DepthFirstRecursive(Node root, List<Node> accuFilter, SomeHelper helper) {
return root.GetChildren().AsObservable()
//here we cut traversal:
.Where(n => !accuFilter.Contains(n))
//cannot do SelectMany, because we want sequential processing:
.Select(n => DepthFirstRecursive(n, accuFilter, helper)).Concat()
.Concat(Observable.Return(root))
//adding results to accumulator
.Do(accuFilter.Add)
}
}
class Node : IEquatable<Node> {
public IEnumerable<Node> GetChildren(SomeHelper helper) {
//produce child nodes
}
...
}
アキュムレータはきれいではありません。これは基本的に、それ以外の場合はエレガントなリアクティブ実装によって織り込まれた副作用です。Rx を使用してそれを取り除くにはどうすればよいですか? Observable.Distinct()
チェーンの最後 ( がある場所) でのみ動作するため、それをカットするつもりはありません (しゃれが意図されてい.Do
ます)。
また、ヘルパーを使用すると、「暗黙的にキャプチャされたクロージャー: ヘルパー」という警告=>
が.Where
. この警告が関連しているとは思いません。それは...ですか?どうすればそれを取り除くことができますか?