2020-12-28 14:55:48 +08:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
|
|
|
|
|
|
namespace Hncore.Infrastructure.Tree
|
|
|
|
|
|
{
|
|
|
|
|
|
public class DataTree
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
///
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="topPredicate">得到第一级节点条件</param>
|
|
|
|
|
|
/// <param name="childPredicate">得到孩子得条件</param>
|
|
|
|
|
|
public static DataNode<TData> Load<TData>(IEnumerable<TData> datas, Func<TData, bool> topPredicate, Func<TData, TData, bool> childPredicate) where TData : new()
|
|
|
|
|
|
{
|
|
|
|
|
|
var root = new DataNode<TData>(new TData() { });
|
|
|
|
|
|
if (datas == null || datas.Count() == 0)
|
|
|
|
|
|
return root;
|
|
|
|
|
|
var tops = datas.Where(topPredicate);
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var p in tops)
|
|
|
|
|
|
{
|
|
|
|
|
|
LoadChildren(datas, root, p, childPredicate);
|
|
|
|
|
|
}
|
|
|
|
|
|
return root;
|
|
|
|
|
|
}
|
|
|
|
|
|
private static void LoadChildren<TData>(IEnumerable<TData> datas,DataNode<TData> topNode, TData p, Func<TData,TData, bool> childPredicate)
|
|
|
|
|
|
{
|
|
|
|
|
|
var pNode = new DataNode<TData>(p);
|
|
|
|
|
|
pNode.Parent = topNode;
|
|
|
|
|
|
topNode.Children.Add(pNode);
|
|
|
|
|
|
|
|
|
|
|
|
var childDatas = datas.Where(item=>childPredicate(p,item)) ;
|
|
|
|
|
|
|
|
|
|
|
|
if (childDatas.Count() > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var childData in childDatas)
|
|
|
|
|
|
{
|
|
|
|
|
|
LoadChildren(datas,pNode, childData, childPredicate);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static void Traverse<TData>(DataNode<TData> rootNode, Action<DataNode<TData>> act, bool root = true)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (root)
|
|
|
|
|
|
{
|
|
|
|
|
|
rootNode.Traverse(act);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
rootNode.Children.ForEach(item =>
|
|
|
|
|
|
{
|
|
|
|
|
|
item.Traverse(act);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|