/// <summary> /// Gets the ancestors of a node including itself. /// </summary> /// <param name="tree"> /// The tree. /// </param> /// <param name="predicate"> /// The predicate. /// </param> /// <typeparam name="TNode"> /// The type of the tree node value /// </typeparam> /// <returns> /// The <see cref="IEnumerable{TreeNode}"/>. /// </returns> internal static IEnumerable<TreeNode<TNode>> AncestorsOrSelf<TNode>( this TreeNode<TNode> tree, Expression<Func<TreeNode<TNode>, bool>> predicate = null) where TNode : IHasKeyId { if (tree.Parent == null) return Enumerable.Empty<TreeNode<TNode>>(); var visitor = new NodeAggregatorTreeNodeVisitor<TNode>(); tree.Climb(visitor); var nodes = visitor.Nodes.AsQueryable(); return predicate == null ? nodes : nodes.Where(predicate); }
/// <summary> /// Gets the descendants of a node. /// </summary> /// <param name="tree"> /// The tree. /// </param> /// <param name="predicate"> /// The predicate. /// </param> /// <typeparam name="TNode"> /// The type of the tree node value /// </typeparam> /// <returns> /// The <see cref="IEnumerable{TreeNode}"/>. /// </returns> internal static IEnumerable<TreeNode<TNode>> Descendants<TNode>( this TreeNode<TNode> tree, Expression<Func<TreeNode<TNode>, bool>> predicate = null) where TNode : IHasKeyId { var visitor = new NodeAggregatorTreeNodeVisitor<TNode>(); tree.Traverse(visitor); // the visitor will pick up the tree itself in the traversal so we have to remove it var nodes = visitor.Nodes.Where(x => x.Value.Key != tree.Value.Key).AsQueryable(); return predicate == null ? nodes : nodes.Where(predicate); }