C# List 轉 Tree 公共方法


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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM