Пример #1
0
 /// <summary>
 /// Производит выборку поддеревьев узла, указанного <paramref name="hnd"/>.
 /// <para>Порядок обхода — breadth-first.</para>
 /// </summary>
 /// <typeparam name="T">Тип узла дерева.</typeparam>
 /// <param name="hnd">
 /// Узел.
 /// </param>
 /// <param name="predicate">Предикат выборки поддерева.</param>
 /// <param name="childrenSelector">Селектор дочерных узлов.</param>
 /// <returns>Объект <see cref="IEnumerable{T}"/>.</returns>
 public static IEnumerable <T> Subtrees <T>(this SingleTreeNodeUtilitiesHandle <T> hnd, Func <T, bool> predicate, Func <T, IEnumerable <T> > childrenSelector)
 {
     predicate.EnsureNotNull(nameof(predicate));
     childrenSelector.EnsureNotNull(nameof(childrenSelector));
     //
     if (predicate(arg: hnd.Source))
     {
         yield return(hnd.Source);
     }
     else
     {
         var traversal = new Queue <T>(collection: hnd.Source.Sequence());
         for (; traversal.Count > 0;)
         {
             var current = traversal.Dequeue();
             foreach (var child in childrenSelector(arg: current).EmptyIfNull())
             {
                 if (predicate(child))
                 {
                     yield return(child);
                 }
                 else
                 {
                     traversal.Enqueue(child);
                 }
             }
         }
     }
 }
Пример #2
0
        public static IEnumerable <T> Ancestors <T>(this SingleTreeNodeUtilitiesHandle <T> hnd, Func <T, T> parentSelector)
        {
            parentSelector.EnsureNotNull(nameof(parentSelector));
            //
            var parent = parentSelector(hnd.Source);

            for (; parent != null;)
            {
                yield return(parent);

                parent = parentSelector(parent);
            }
        }
Пример #3
0
        public static TResult Transform <TSource, TResult>(this SingleTreeNodeUtilitiesHandle <TSource> hnd, Func <TSource, IEnumerable <TSource> > childrenSelector, Func <TSource, IEnumerable <TResult>, TResult> transform)
        {
            childrenSelector.EnsureNotNull(nameof(childrenSelector));
            transform.EnsureNotNull(nameof(transform));
            //
            var root           = new P_TreeNodeTransformState <TSource, TResult>(hnd.Source);
            var traversalStack = new Stack <P_TreeNodeTransformState <TSource, TResult> >(root.Sequence());

            for (; traversalStack.Count > 0;)
            {
                var currentTraversalEntry = traversalStack.Peek();
                //
                var initialSizeOfTraversalStack = traversalStack.Count;
                if (currentTraversalEntry.SourceChildren == null)
                {
                    currentTraversalEntry.SourceChildren =
                        childrenSelector(currentTraversalEntry.Source)
                        .EmptyIfNull()
                        .ToArray();
                    for (var i = currentTraversalEntry.SourceChildren.Length - 1; i > -1; i--)
                    {
                        traversalStack
                        .Push(
                            new P_TreeNodeTransformState <TSource, TResult>(
                                currentTraversalEntry,
                                currentTraversalEntry.SourceChildren[i]));
                    }
                }
                //
                if (initialSizeOfTraversalStack == traversalStack.Count)
                {
                    traversalStack.Pop();
                    if (!ReferenceEquals(currentTraversalEntry, root))
                    {
                        currentTraversalEntry
                        .Parent
                        .TransformedSourceChildren
                        .Add(transform(currentTraversalEntry.Source, currentTraversalEntry.TransformedSourceChildren));
                    }
                }
            }
            return(transform(root.Source, root.TransformedSourceChildren));
        }
Пример #4
0
        public static IEnumerable <T> Descendants <T>(this SingleTreeNodeUtilitiesHandle <T> hnd, Func <T, IEnumerable <T> > childrenSelector)
        {
            childrenSelector.EnsureNotNull(nameof(childrenSelector));
            //
            var traversalBuffer = new Queue <T>();

            foreach (var child in childrenSelector(arg: hnd.Source).EmptyIfNull())
            {
                traversalBuffer.Enqueue(child);
            }
            for (; traversalBuffer.Count > 0;)
            {
                var current = traversalBuffer.Dequeue();
                foreach (var child in childrenSelector(current).EmptyIfNull())
                {
                    traversalBuffer.Enqueue(child);
                }
                yield return(current);
            }
        }
Пример #5
0
 public static IEnumerable <T> SelfAndDescendants <T>(this SingleTreeNodeUtilitiesHandle <T> hnd, Func <T, IEnumerable <T> > childrenSelector)
 => Enumerable.Concat(first: hnd.Source.Sequence(), second: Descendants(hnd: hnd, childrenSelector: childrenSelector));
Пример #6
0
 public static IEnumerable <T> SelfAndAncestors <T>(this SingleTreeNodeUtilitiesHandle <T> hnd, Func <T, T> parentSelector)
 => Enumerable.Concat(first: hnd.Source.Sequence(), second: Ancestors(hnd: hnd, parentSelector: parentSelector));