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