namespace Kit.Helpers; public class TreeNode { public TKey Id { get; set; } public TKey ParentId { get; set; } public TEntity Item { get; set; } public int Layer { get; set; } public List> ChildNodes { get; set; } public bool HasContent { get; set; } public TreeNode() { ChildNodes = new List>(); } } public static class TreeHelper { /// Преобразование дерева с родительскими указателями в дерево с дочерними указателями public static IEnumerable> ConvertToTreeNodes(this IEnumerable entities, Func getId, Func getParentId, Func idEquals, TKey parentIdEmpty) { IEnumerable> treeNodes = entities.Select(x => new TreeNode { Id = getId(x), ParentId = getParentId(x), Item = x, }).ToList(); treeNodes.ForEach(treeNode => { treeNode.ChildNodes = treeNodes.Where(x => idEquals(treeNode.Id, x.ParentId)).ToList(); }); return treeNodes.Where(x => x.ParentId.Equals(parentIdEmpty)).ToList(); } public static List> FlattenTree(this IEnumerable> nodes, Func, TOrderKey> getSortKey, int layer = 0) { var result = new List>(); if (nodes.IsNullOrEmpty()) return result; foreach (var node in nodes.OrderBy(getSortKey)) { node.Layer = layer; result.Add(node); result.AddRange(FlattenTree(node.ChildNodes, getSortKey, layer + 1)); } return result; } public static void SelectSubtreeById(this List nodes, List subtree, TEntityId rootId, Func getId, Func getParentId) where TEntity : class where TEntityId : struct { TEntity? node = nodes.FirstOrDefault(n => getId(n).Equals(rootId)); if (node != null) { subtree.Add(node); List children = nodes.Where(n => getParentId(n).Equals(rootId)).ToList(); foreach (var child in children) { SelectSubtreeById(nodes, subtree, getId(child), getId, getParentId); } } } }