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))
{
yield return parent;
}
else
{
yield break;
}
parent = parent.Parent;
}
}
Am i right saying Jon’s answer will create 2 enumerators?
How about:
That give
nullif the right node can’t be found.EDIT: Okay, if you need the complete sequence from bottom to top, you can just use:
where
TakeUntilis a method likeTakeWhilebut 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: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.