用C# 寫了個List數據結構轉樹形數據結構的公共擴展方法
/// <summary>
/// 將列表轉換為樹形結構
/// </summary>
/// <typeparam name="T">類型</typeparam>
/// <param name="list">數據</param>
/// <param name="rootwhere">根條件</param>
/// <param name="childswhere">節點條件</param>
/// <param name="addchilds">添加子節點</param>
/// <param name="entity"></param>
/// <returns></returns>
public static List<T> ToTree<T>(this List<T> list, Func<T, T, bool> rootwhere, Func<T, T, bool> childswhere, Action<T, IEnumerable<T>> addchilds, T entity = default(T))
{
var treelist = new List<T>();
//空樹
if (list == null || list.Count == 0)
{
return treelist;
}
if (!list.Any<T>(e => rootwhere(entity, e)))
{
return treelist;
}
//樹根
if (list.Any<T>(e => rootwhere(entity, e)))
{
treelist.AddRange(list.Where(e => rootwhere(entity, e)));
}
//樹葉
foreach (var item in treelist)
{
if (list.Any(e => childswhere(item, e)))
{
var nodedata = list.Where(e => childswhere(item, e)).ToList();
foreach (var child in nodedata)
{
//添加子集
var data = list.ToTree(childswhere, childswhere, addchilds, child);
addchilds(child, data);
}
addchilds(item, nodedata);
}
}
return treelist;
}
方法說明:
第一個參數:根節點的條件
第二個參數:根節點和子節點的關系(注意,這地方如果條件不充分,會導致異常,無限遞歸)
第三個參數:當前數據添加子集
調用示例1、(id--->pid)
var treedata = list.ToTree<TTest>((r, c) =>
{
return c.Pid == 0;
},
(r, c) =>
{
return r.Id == c.Pid;
},
(r, datalist) =>
{
r.Childs = r.Childs ?? new List<TTest>();
r.Childs.AddRange(datalist);
});
調用示例2、(LevelCode)
treedata2 = liststr2.ToTree<TTest>((r, c) => c.LevelCode.Length == 6, (r, c) =>
{
if (r == null || c == null)
{
return false;
}
if ((r.LevelCode.Length + 6 == c.LevelCode.Length) &&
r.LevelCode == c.LevelCode.Substring(0, r.LevelCode.Length))
{
return true;
}
else
{
return false;
}
},
(r, datalist) => {
r.Childs = r.Childs ?? new List<TTest>();
r.Childs.AddRange(datalist);
});
