Kit.Core/LibCommon/Kit.Core.Helpers/TreeHelper.cs

66 lines
2.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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);
}
}
}
}