/// <summary> /// 获取子孙数据(深度优先,后序) /// </summary> /// <typeparam name="T">数据类型</typeparam> /// <param name="root">根</param> /// <param name="predicate">子孙筛选条件</param> /// <returns>筛选的子孙</returns> public static IEnumerable <IHierarchical <T> > GetDescendantsDfsLrd <T>(this IHierarchical <T> root, Func <IHierarchical <T>, bool> predicate = null) { var children = predicate == null ? root.Children : root.Children.Where(predicate); Stack <IHierarchical <T> > stack = new Stack <IHierarchical <T> >(children.Reverse()); IHierarchical <T> lastAccessedNode = null; while (stack.Count > 0) { var node = stack.Peek(); if (node.Children.Any() && node.Children.Last() != lastAccessedNode) { children = predicate == null ? node.Children : node.Children.Where(predicate); foreach (IHierarchical <T> child in children.Reverse()) { stack.Push(child); } } else { yield return(node); lastAccessedNode = node; stack.Pop(); } } }
public static TAncestor GetAncestor <T, TAncestor>(this IHierarchical <T> source, bool includingItselt = false) where TAncestor : class { if (source == null) { throw new ArgumentNullException("source"); } if (includingItselt) { var itself = source as TAncestor; if (itself != null) { return(itself); } } var castedParent = source.Parent as TAncestor; if (castedParent != null) { return(castedParent); } var hierarhicalParent = source.Parent as IHierarchical <T>; if (hierarhicalParent == null) { return(null); } return(GetAncestor <T, TAncestor>(hierarhicalParent)); }
private void TraverseNodes <U>(U closureArg, IHierarchical item, Action <U, SkipTreeNode> traverseFn, bool includeDisabled) { SkipTreeNode node; if (nodeMap.TryGetValue(item.UniqueId, out node)) { TraverseNodesStep(closureArg, node, traverseFn, includeDisabled); return; } SkipTreeNode parent = FindParent(item); parent = parent ?? root; SkipTreeNode ptr = parent.firstChild; while (ptr != null) { if (IsDescendantOf(ptr.item, item)) { TraverseNodesStep(closureArg, ptr, traverseFn, includeDisabled); } ptr = ptr.nextSibling; } }
/// <summary> /// 转换为可枚举集合 /// </summary> /// <typeparam name="T">数据类型</typeparam> /// <param name="root">根</param> /// <param name="childSelector">下层数据选择器</param> /// <param name="predicate">子孙筛选条件</param> /// <param name="enumerateType">枚举方式</param> /// <returns>已枚举的集合</returns> public static IEnumerable <IHierarchical <T> > AsEnumerable <T>(this IHierarchical <T> root, Func <IHierarchical <T>, IEnumerable <IHierarchical <T> > > childSelector, Func <IHierarchical <T>, bool> predicate, EnumerateType enumerateType = EnumerateType.DfsDlr) { yield return(root); switch (enumerateType) { case EnumerateType.DfsDlr: foreach (var descendant in GetDescendantDfsDlr(root, childSelector, predicate)) { yield return(descendant); } break; case EnumerateType.Bfs: foreach (var descendant in GetDescendantsBfs(root, childSelector, predicate)) { yield return(descendant); } break; } }
public void TraversePreOrder <U>(IHierarchical item, U closureArg, Action <U, T> traverseFn, bool includeDisabled = false) { SkipTreeNode node; if (nodeMap.TryGetValue(item.UniqueId, out node)) { TraversePreOrderCallbackStep(node, closureArg, traverseFn, includeDisabled); return; } SkipTreeNode parent = FindParent(item); parent = parent ?? root; SkipTreeNode ptr = parent.firstChild; while (ptr != null) { if (IsDescendantOf(ptr.item, item)) { TraversePreOrderCallbackStep(ptr, closureArg, traverseFn, includeDisabled); } ptr = ptr.nextSibling; } }
/// <summary> /// 获取子孙数据(深度优先,先序) /// </summary> /// <typeparam name="T">数据类型</typeparam> /// <param name="root">根</param> /// <param name="predicate">子孙筛选条件</param> /// <returns>筛选的子孙</returns> public static IEnumerable <IHierarchical <T> > GetDescendantsDfsDlr <T>(this IHierarchical <T> root, Func <IHierarchical <T>, bool> predicate = null) { var children = predicate == null ? root.Children : root.Children.Where(predicate); Stack <IHierarchical <T> > stack = new Stack <IHierarchical <T> >(children.Reverse()); while (stack.Count > 0) { IHierarchical <T> node = stack.Pop(); yield return(node); children = predicate == null ? node.Children : node.Children.Where(predicate); foreach (IHierarchical <T> child in children.Reverse()) { stack.Push(child); } } #region 递归方式 //foreach (T t in childSelector(root)) //{ // if (predicate(t)) // yield return t; // foreach (T child in GetDescendantDfsDlr(t, childSelector, predicate)) // yield return child; //} #endregion 递归方式 }
public void ConditionalTraversePreOrder <U>(IHierarchical start, U closureArg, Func <T, U, bool> traverseFn) { if (start == null) { ConditionalTraversePreOrderStep(root, closureArg, traverseFn); return; } SkipTreeNode node; if (nodeMap.TryGetValue(start.UniqueId, out node)) { ConditionalTraversePreOrderStep(node, closureArg, traverseFn); return; } SkipTreeNode parent = FindParent(start); parent = parent ?? root; SkipTreeNode ptr = parent.firstChild; while (ptr != null) { if (IsDescendantOf(ptr.item, start)) { if (traverseFn(ptr.item, closureArg)) { ConditionalTraversePreOrderStep(ptr, closureArg, traverseFn); } } ptr = ptr.nextSibling; } }
/// <summary> /// 设置节点的双亲和子节点引用 /// </summary> /// <typeparam name="T">节点类型</typeparam> /// <param name="root">根节点</param> /// <param name="childrenSelector">子节点选择器</param> /// <param name="clearChildrenBeforeSet">是否在设置子节点前清空子节点集合</param> /// <param name="parentSetter">双亲节点设置器,第一个参数为待设置引用的节点,第二个参数为第一个参数的双亲节点</param> /// <returns>原始根节点</returns> public static T SetParentChildren <T>(this IHierarchical <T> root, Func <T, ICollection <T> > childrenSelector, bool clearChildrenBeforeSet = false, Action <T, T> parentSetter = null) { if (childrenSelector == null) { throw new ArgumentNullException(nameof(childrenSelector)); } foreach (var node in root.AsEnumerable()) { parentSetter?.Invoke(node.Current, node.Parent != null ? node.Parent.Current : default(T)); var children = childrenSelector.Invoke(node.Current); if (children == null) { throw new InvalidOperationException("子节点集合为 null"); } if (clearChildrenBeforeSet) { children.Clear(); } foreach (var child in node.Children) { children.Add(child.Current); } } return(root.Current); }
public void UpdateItemParent(IHierarchical element) { T item = GetItem(element); if (item != null) { SkipTreeNode node = nodeMap[item.UniqueId]; SkipTreeNode parent = node.parent; SkipTreeNode nodeNext = node.nextSibling; SkipTreeNode nodePrev = FindPreviousSibling(node); if (nodePrev != null) { nodePrev.nextSibling = nodeNext; } else { parent.firstChild = nodeNext; } parent.childCount--; node.parent = null; parent = FindParent(element); Insert(parent ?? root, node); } }
//递归父节点跟随其全选或全不选 private static void FooParent(IHierarchical root) { if (root.Parent == null) { return; } //遍历该节点的兄弟节点 var brotherNodeCheckedCount = root.Parent.Children.Count(node => ((ISelectable)node).IsSelected == true); //兄弟节点全没选 if (brotherNodeCheckedCount == 0) { var parentNode = root.Parent; ((ISelectable)parentNode).IsSelected = false; //其父节点也不选 FooParent(parentNode); } //兄弟节点中只要有一个被选 if (brotherNodeCheckedCount == 1) { var parentNode = root.Parent; ((ISelectable)parentNode).IsSelected = true; //其父节点也被选 FooParent(parentNode); } }
private void Insert(SkipTreeNode parent, SkipTreeNode inserted) { SkipTreeNode ptr = parent.firstChild; IHierarchical element = inserted.item; // set parent // walk through current parent's children // if any of those are descendants of inserted // remove from parent // attach as first sibling to inserted SkipTreeNode insertedLastChild = null; SkipTreeNode parentPreviousChild = null; while (ptr != null) { IHierarchical currentElement = ptr.item; if (IsDescendantOf(currentElement, element)) { SkipTreeNode next = ptr.nextSibling; if (ptr == parent.firstChild) { parent.firstChild = next; } else if (parentPreviousChild != null) { parentPreviousChild.nextSibling = next; } if (insertedLastChild != null) { insertedLastChild.nextSibling = ptr; } else { inserted.firstChild = ptr; } ptr.parent.childCount--; ptr.parent = inserted; inserted.childCount++; ptr.nextSibling = null; insertedLastChild = ptr; ptr = next; } else { parentPreviousChild = ptr; ptr = ptr.nextSibling; } } parent.childCount++; inserted.parent = parent; inserted.isDisabled = parent.isDisabled; inserted.nextSibling = parent.firstChild; parent.firstChild = inserted; }
public static IEnumerable <TAncestor> GetDescendants <T, TAncestor>(this IHierarchical <T> source, bool includingItselt = true) where TAncestor : class { var result = new Collection <TAncestor>(); CollectDescendants(source, includingItselt, result); return(result); }
/// <summary> /// 判断节点是否是指定节点的祖先节点 /// </summary> /// <typeparam name="T">节点数据类型</typeparam> /// <param name="node">待判断的节点</param> /// <param name="target">目标节点</param> /// <returns>判断结果</returns> public static bool IsAncestorOf <T>(this IHierarchical <T> node, IHierarchical <T> target) { if (node.Root != target.Root) { throw new InvalidOperationException($"{nameof(node)} and {nameof(target)} are not at same tree."); } return(target.Ancestors.SingleOrDefault(n => n == node) != null); }
/// <summary> /// 判断节点是否是指定节点的后代节点 /// </summary> /// <typeparam name="T">节点数据类型</typeparam> /// <param name="node">待判断的节点</param> /// <param name="target">目标节点</param> /// <returns>判断结果</returns> public static bool IsDescendantOf <T>(this IHierarchical <T> node, IHierarchical <T> target) { if (node.Root != target.Root) { throw new InvalidOperationException($"{nameof(node)} and {nameof(target)} are not at same tree."); } return(target.IsAncestorOf(node)); }
/// <summary> /// 获取从当前节点到指定节点的路径 /// </summary> /// <typeparam name="T">节点数据类型</typeparam> /// <param name="node">当前节点(起点)</param> /// <param name="to">目标节点(终点)</param> /// <returns>按从当前节点到目标节点顺序经过的节点集合</returns> public static IEnumerable <IHierarchical <T> > GetPathToNode <T>(this IHierarchical <T> node, IHierarchical <T> to) { if (node.Root != to.Root) { throw new InvalidOperationException($"{nameof(node)} and {nameof(to)} are not at same tree."); } return(to.GetPathFromNode(node)); }
public IContainer Add(IHierarchical child) { if (child != null) { children.Add(child); child.Parent = this; } return(this); }
public int GetChildCount(IHierarchical item) { SkipTreeNode node; if (!nodeMap.TryGetValue(item.UniqueId, out node)) { return(0); } return(node.childCount); }
public static IHierarchical FindRootOrganization(this IHierarchical org) { if (org.Parent == null) { return(org); } else { return(FindRootOrganization(org.Parent)); } }
/// <summary> /// 获取从指定节点到当前节点的路径 /// </summary> /// <typeparam name="T">节点数据类型</typeparam> /// <param name="node">当前节点(终点)</param> /// <param name="from">目标节点(起点)</param> /// <returns>按从目标节点到当前节点顺序经过的节点集合</returns> public static IEnumerable <IHierarchical <T> > GetPathFromNode <T>(this IHierarchical <T> node, IHierarchical <T> from) { if (node.Root != from.Root) { throw new InvalidOperationException($"{nameof(node)} and {nameof(from)} are not at same tree."); } yield return(from); //起点必然是需要的 if (node == from) { yield break; //如果终点就是起点,那么可以直接结束路径查找了 } //只有终点和起点不存在双亲孩子关系时才需要执行内部代码,否则直接返回终点即可 if (!(node.Parent == from || node.Children.Any(n => n == from))) { var nearestCommonAncestor = node.GetNearestCommonAncestor(from); //如果起点不是终点的祖先,需要先返回从起点的双亲到最近公共祖先 //(不包括最近公共祖先。最近公共祖先可能就是终点,返回的话会导致终点被返回两次。终点会在方法末尾统一返回)的路径 if (!from.IsAncestorOf(node)) { foreach (var ancestor in from.Ancestors) { if (ancestor != nearestCommonAncestor) { yield return(ancestor); } else { break; } } } //如果最近公共祖先不是终点,返回从最近公共祖先到终点(不包括终点,原因不再赘述)的路径 if (nearestCommonAncestor != node) { var ancestorsOfNode = node.Ancestors.ToArray(); for (int i = Array.IndexOf(ancestorsOfNode, nearestCommonAncestor); i >= 0; i--) { yield return(ancestorsOfNode[i]); } } } yield return(node); //最后返回终点 }
private static bool IsDescendantOf(IHierarchical child, IHierarchical parent) { IHierarchical ptr = child; while (ptr != null) { if (ptr == parent.Element) { return(true); } ptr = ptr.Parent; } return(false); }
private SkipTreeNode FindParent(IHierarchical element) { IHierarchical ptr = element.Parent; while (ptr != null) { SkipTreeNode node; if (nodeMap.TryGetValue(ptr.UniqueId, out node)) { return(node); } ptr = ptr.Parent; } return(null); }
/// <summary> /// 获取子孙数据(广度优先) /// </summary> /// <typeparam name="T">数据类型</typeparam> /// <param name="root">根</param> /// <param name="predicate">子孙筛选条件</param> /// <returns>筛选的子孙</returns> public static IEnumerable <IHierarchical <T> > GetDescendantsBfs <T>(this IHierarchical <T> root, Func <IHierarchical <T>, bool> predicate = null) { predicate = predicate ?? (t => true); Queue <IHierarchical <T> > queue = new Queue <IHierarchical <T> >(root.Children.Where(predicate)); while (queue.Count > 0) { IHierarchical <T> node = queue.Dequeue(); yield return(node); foreach (IHierarchical <T> child in node.Children.Where(predicate)) { queue.Enqueue(child); } } }
public void RemoveItem(IHierarchical item) { SkipTreeNode node; IHierarchical element = item.Element; if (!nodeMap.TryGetValue(element.UniqueId, out node)) { return; } SkipTreeNode parent = node.parent; SkipTreeNode ptr = node.firstChild; SkipTreeNode nodeNext = node.nextSibling; SkipTreeNode nodePrev = FindPreviousSibling(node); SkipTreeNode lastChild = null; parent.childCount--; while (ptr != null) { ptr.parent = node.parent; node.parent.childCount++; lastChild = ptr; ptr = ptr.nextSibling; } if (parent.firstChild == node) { parent.firstChild = node.firstChild; } else { nodePrev.nextSibling = node.firstChild; if (lastChild != null) { lastChild.nextSibling = nodeNext; } } node.parent = null; node.item = default(T); node.nextSibling = null; node.firstChild = null; nodeMap.Remove(element.UniqueId); onTreeChanged?.Invoke(TreeChangeType.ItemRemoved); }
public void AddItem(T item) { SkipTreeNode node; IHierarchical element = item.Element; if (nodeMap.TryGetValue(element.UniqueId, out node)) { return; } node = new SkipTreeNode(item); nodeMap[element.UniqueId] = node; SkipTreeNode parent = FindParent(element); Insert(parent ?? root, node); onTreeChanged?.Invoke(TreeChangeType.ItemAdded); }
/// <summary> /// 获取节点与指定节点的最近公共祖先节点 /// </summary> /// <typeparam name="T">节点数据类型</typeparam> /// <param name="node">待查找的节点</param> /// <param name="target">目标节点</param> /// <returns>最近的公共祖先节点</returns> public static IHierarchical <T> GetNearestCommonAncestor <T>(this IHierarchical <T> node, IHierarchical <T> target) { if (node.Root != target.Root) { throw new InvalidOperationException($"{nameof(node)} and {nameof(target)} are not at same tree."); } if (node.IsAncestorOf(target)) { return(node); } if (target.IsAncestorOf(node)) { return(target); } return(node.Ancestors.Intersect(target.Ancestors).OrderByDescending(no => no.Level).First()); }
public bool CanInsert(object parent, object child) { IHierarchical hierarchical = parent.As <IHierarchical>(); if (hierarchical == null) { return(false); } ILockable lockable = parent.As <ILockable>(); if (lockable != null && lockable.IsLocked) { return(false); } DomNode parentNode = parent.As <DomNode>(); IEnumerable <object> items = Util.ConvertData(child, false); bool canInsert = false; foreach (object item in items) { DomNode childNode = item as DomNode; if (parentNode != null && childNode != null) { if ((parentNode.IsDescendantOf(childNode) || parentNode == childNode || parentNode == childNode.Parent)) { return(false); } } IResource res = item as IResource; IGameObject gob = m_resourceConverterService.Convert(res); if (!hierarchical.CanAddChild(item) && !hierarchical.CanAddChild(gob)) { return(false); } canInsert = true; } return(canInsert); }
public Router FindRouterInHierarchy(UIElement element) { IHierarchical ptr = element; while (ptr != null) { for (int i = 0; i < m_Routers.Count; i++) { if (m_Routers[i].hostId == ptr.UniqueId) { return(m_Routers[i]); } } ptr = ptr.Parent; } return(null); }
public int GetActiveChildCount(IHierarchical element) { SkipTreeNode node; if (!nodeMap.TryGetValue(element.UniqueId, out node)) { return(0); } SkipTreeNode ptr = node.parent.firstChild; int count = 0; while (ptr != null) { count += !ptr.isDisabled ? 1 : 0; ptr = ptr.nextSibling; } return(count); }
public void TraverseAncestors <U>(IHierarchical start, U closureArg, Action <T, U> traverseFn) { SkipTreeNode node; SkipTreeNode ptr; if (nodeMap.TryGetValue(start.UniqueId, out node)) { ptr = node.parent; } else { ptr = FindParent(start); } while (ptr != null) { traverseFn(ptr.item, closureArg); ptr = ptr.parent; } }
public TreeNode GetTraversableTree(T item, bool includeDisabled = false) { SkipTreeNode node; IHierarchical element = item.Element; if (!nodeMap.TryGetValue(element.UniqueId, out node)) { SkipTreeNode parent = FindParent(item); parent = parent ?? root; SkipTreeNode ptr = parent.firstChild; while (ptr != null) { if (!includeDisabled && ptr.isDisabled) { ptr = ptr.nextSibling; continue; } if (IsDescendantOf(ptr.item, item)) { scratchNodeList.Add(ptr); } ptr = ptr.nextSibling; } TreeNode[] children = scratchNodeList.Count == 0 ? TreeNode.EmptyArray : new TreeNode[scratchNodeList.Count]; for (int i = 0; i < children.Length; i++) { children[i] = GetChildTree(scratchNodeList[i], includeDisabled); } return(new TreeNode(item, false, children)); } return(GetChildTree(node, includeDisabled)); }
private bool FindServiceOnSpecOrSpecSuperclass(IHierarchical spec) { if (spec == null) { return false; } if (spec == OnType) { return true; } return FindServiceOnSpecOrSpecSuperclass(spec.Superclass); }