I have a Node Tree i like to iterate to find all ancestors until a given point (node) in the tree. That way i can inserted/save it back to my db. So far i have something like the following which has been proven very useful, so far:
public IEnumerable<INode> Ancestors()
{
var parent = this.Parent;
while (parent != null)
{
yield return parent;
parent = parent.Parent;
}
}
I think, I should be passing a Func or Func in order to stop/break the sequence.
What would it be the best implementation?.Ta
Edited: Given the answers below. Im thinking going for something more performant like:
public IEnumerable<INode> Ancestors(Func<INode, bool> predicate)
{
var parent = this.Parent;
while (parent != null)
{
if (predicate(parent))
{
yiel开发者_JS百科d return parent;
}
else
{
yield break;
}
parent = parent.Parent;
}
}
Am i right saying Jon's answer will create 2 enumerators?
How about:
var desiredNode = child.Ancestors().FirstOrDefault(node => node.Id == desiredId);
That give null
if the right node can't be found.
EDIT: Okay, if you need the complete sequence from bottom to top, you can just use:
var nodes = child.Ancestors().TakeUntil(node => node.Id == desiredId);
where TakeUntil
is a method like TakeWhile
but which includes the final node which matched the predicate. You can find a sample implementation in MoreLINQ. If you don't mind the lack of argument validation (which MoreLINQ does provide), it's very simple to write:
public static IEnumerable<T> TakeUntil<T>(this IEnumerable<T> source,
Func<T, bool> predicate)
{
foreach (T item in source)
{
yield return item;
if (predicate(item))
{
yield break;
}
}
}
You could build the functionality into the Ancestors()
method, but it's mixing two responsibilities into one relatively-complex function, instead of having two simple functions which can be composed with other simple functions in a very general way.
Try this:
public IEnumerable<INode> Ancestors(Func<INode, bool> takeUntil)
{
var parent = this.Parent;
while (parent != null)
{
yield return parent;
if (takeUntil(parent))
{
break;
}
parent = parent.Parent;
}
}
...
var ancestors = node.Ancestors(n => n.Id == 123);
精彩评论