public static HierarchyList <T> FromDictionaryFreely <TSub>(T root, [NotNull] IReadOnlyDictionary <T, TSub> inputMap) where TSub : IEnumerable <T> { var cachedMap = inputMap.ToDictionary(a => a.Key, a => a.Value); var hierarchy = new HierarchyList <T>(root); InitializeHierarchy(hierarchy.Root, cachedMap); return(hierarchy); void InitializeHierarchy(HierarchyListNode <T> node, IDictionary <T, TSub> map) { if (map.TryGetValue(node.Value, out var subItems)) { map.Remove(node.Value); foreach (var subCommandInfo in subItems) { var newNode = node.AddChildren(subCommandInfo); InitializeHierarchy(newNode, map); } } } }
public static IReadOnlyDictionary <T, IReadOnlyCollection <T> > ToDictionaryMap <T>([NotNull] this HierarchyList <T> tree) { return(tree.Root.ToDictionaryMap()); }
public static HierarchyList <T> FromDictionary <TSub>([NotNull] IReadOnlyDictionary <T, TSub> inputMap, IEqualityComparer <T> comparer = null) where TSub : IEnumerable <T> { comparer ??= EqualityComparer <T> .Default; var cache = new HashSet <T>(); var cachedMap = inputMap.ToDictionary(a => a.Key, a => a.Value); var determinedRoot = inputMap.Select(a => a.Key).Except(inputMap.SelectMany(a => a.Value)).ToList(); if (determinedRoot.Count == 0) { throw new ArgumentException("Root cannot be detected."); } if (determinedRoot.Count > 1) { throw new ArgumentException("Multiple roots found."); } var root = determinedRoot[0]; var hierarchy = new HierarchyList <T>(root); InitializeHierarchy(hierarchy.Root, cachedMap); return(hierarchy); void InitializeHierarchy(HierarchyListNode <T> node, IDictionary <T, TSub> map) { if (cache.Contains(node.Value)) { if (node.Parent != null && node.Value.Equals(node.Parent.Value)) { // self reference throw new ArgumentException($"Self reference found for: {node.Value}"); } else { var parents = inputMap.Where(a => a.Value.Any(b => b.Equals(node.Value)) || comparer.Equals(a.Key, root)).ToList(); // multiple parents throw new ArgumentException($"Multiple parent nodes ({parents.Count()}) found for: {node.Value}\nParents: {string.Join(";", parents.Select(a => a.Key.ToString()))}"); } } cache.Add(node.Value); if (map.TryGetValue(node.Value, out var subItems)) { map.Remove(node.Value); foreach (var subCommandInfo in subItems) { var newNode = node.AddChildren(subCommandInfo); InitializeHierarchy(newNode, map); } } } }
public static bool IsSubTreeOf <T>([NotNull] this HierarchyList <T> tree, [NotNull] HierarchyList <T> otherTree) => otherTree.Root.GetDescendants().Any(a => a == tree.Root);
public static int GetHeight <T>([NotNull] this HierarchyList <T> tree) => tree.Root.GetNodeHeight();
public static int GetDegree <T>([NotNull] this HierarchyList <T> tree) => tree.Max(a => a.GetNodeDegree());
public static IEnumerable <HierarchyListNode <T> > GetLeafNodes <T>([NotNull] this HierarchyList <T> tree) { return(tree.Where(a => a.IsLeafNode())); }
public static IEnumerable <HierarchyListNode <T> > GetBranchNodes <T>([NotNull] this HierarchyList <T> tree) { return(tree.Where(a => TreeNodeExtensions.IsBranchNode <T>(a))); }