C# Net 树帮助类,树节点帮助类(非递归)

C# Net 树帮助类

C# Net 树节点帮助类

优点:非递归,效率可能更高

 

------------------------------------------------------------

------------------------------------------------------------

---------------------文尾看调用方式------------------

------------------------------------------------------------

------------------------------------------------------------

 

创建一个新的文件 ITreeNode.cs 并拷贝代码:

 

    /// <summary>
    /// 树节点
    /// </summary>
    public interface ITreeNode<T>
    {
        /// <summary>
        /// 名称
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// 主键Id
        /// </summary>
        public object Id { get; set; }
        /// <summary>
        /// 父Id
        /// </summary>
        public object Pid { get; set; }
        /// <summary>
        /// 子节点
        /// </summary>
        public List<T> Children { get; set; }
    }

    /// <summary>
    /// 树节点扩展
    /// </summary>
    public static class TreeNodeEx
    {
        /// <summary>
        /// 转为树结构
        /// </summary>
        /// <param name="treeNodes">树节点</param>
        /// <returns>树节点带子节点(Children)</returns>
        public static List<T> ToTree<T>(this List<T> treeNodes) where T : ITreeNode<T>
        {
            if (treeNodes == null || !treeNodes.Any())
                return treeNodes;
            if (treeNodes.Any(o => o.Id == o.Pid))
                throw new Exception("存在id和pid相同的数据,无限循环引用");

            var group = treeNodes.GroupBy(x => x.Pid).ToDictionary(x => x.Key, s => s.ToList());

            foreach (var item in treeNodes)
            {
                if (group.ContainsKey(item.Id))
                {
                    var treeNode = group[item.Id];
                    if (treeNode.Any(o => o.Id == item.Pid && o.Pid == item.Id))
                        throw new Exception("存在id和pid交叉引用(如:{Id='我是你',Pid='你是我'} 和 {Id='你是我',Pid='我是你'})");

                    if (item.Children == null)
                        item.Children = new List<T>();

                    item.Children.AddRange(treeNode);
                }
            }

            //查找顶级节点
            var ids = treeNodes.Select(o => o.Id).Distinct();
            var pids = treeNodes.Select(o => o.Pid).Distinct();
            var c = pids.Except(ids);
            return group.Where(o => c.Contains(o.Key)).SelectMany(o => o.Value).ToList();
        }

        /// <summary>
        /// 将指定的id节点转为树结构
        /// </summary>
        /// <param name="treeNodes">树节点</param>
        /// <param name="id">id节点</param>
        /// <returns>树节点带子节点(Children)</returns>
        public static T ToTree<T>(this List<T> treeNodes, object id) where T : ITreeNode<T>
        {
            if (treeNodes == null)
                return default(T);
            if (!treeNodes.Any())
                return treeNodes.FirstOrDefault();
            if (treeNodes.Any(o => o.Id == o.Pid))
                throw new Exception("存在id和pid相同的数据,无限循环引用");

            var group = treeNodes.GroupBy(x => x.Pid).ToDictionary(x => x.Key, s => s.ToList());

            foreach (var item in treeNodes)
            {
                if (group.ContainsKey(item.Id))
                {
                    var treeNode = group[item.Id];
                    if (treeNode.Any(o => o.Id == item.Pid && o.Pid == item.Id))
                        throw new Exception("存在id和pid交叉引用(如:{Id='我是你',Pid='你是我'} 和 {Id='你是我',Pid='我是你'})");

                    if (item.Children == null)
                        item.Children = new List<T>();

                    item.Children.AddRange(treeNode);
                }
            }

            return treeNodes.FirstOrDefault(o => o.Id == id);
        }

        /// <summary>
        /// 转为树节点
        /// </summary>
        /// <param name="treeNodes">树节点</param>
        /// <returns>树节点带子节点(Children)</returns>
        public static List<T> ToTreeNode<T>(this List<T> treeNodes) where T : ITreeNode<T>
        {
            if (treeNodes == null || !treeNodes.Any())
                return treeNodes;

            List<T> trees = new List<T>();
            foreach (var item in treeNodes)
            {
                trees.Add(item);

                if (item.Children != null && item.Children.Any())
                {
                    var aaa = ToTreeNode(item.Children);
                    trees.AddRange(aaa);
                }
            }
            return trees;
        }
    }

  

------------------------------------------------------------

     ---------------------开始调用------------------

------------------------------------------------------------

 

1.创建一个类 Info.cs 继承 TreeNodeHelper (也可以直接使用TreeNodeHelper,忽略此步骤)

 

    public class Info: TreeNodeHelper
    {
        /// <summary>
        /// 名称
        /// </summary>
        public string MyInfo { get; set; }
    }

 

2.1 调用(方式一)

 

            List<Info> infos = new List<Info>()
            {
                new Info (){Id="重庆",Pid="",MyInfo="a" },
                new Info (){Id="渝中",Pid="重庆",MyInfo="a1" },
                new Info (){Id="北碚",Pid="重庆",MyInfo="a2" },
                new Info (){Id="七星岗",Pid="渝中",MyInfo="a3" },

                new Info (){Id="成都",Pid="四川",MyInfo="a4" },
                new Info (){Id="武侯",Pid="成都",MyInfo="a5" },
                new Info (){Id="龙泉",Pid="成都",MyInfo="a6" },
            };
            var data = infos.ToTree();

 

注:json可复制粘贴到(www.json.cn)中去查看

data效果为(转为json方便查看):

 

[{"MyInfo":"a","Name":null,"Id":"重庆","Pid":"","Children":[{"MyInfo":"a1","Name":null,"Id":"渝中","Pid":"重庆","Children":[{"MyInfo":"a3","Name":null,"Id":"七星岗","Pid":"渝中","Children":[]}]},{"MyInfo":"a2","Name":null,"Id":"北碚","Pid":"重庆","Children":[]}]},{"MyInfo":"a4","Name":null,"Id":"成都","Pid":"四川","Children":[{"MyInfo":"a5","Name":null,"Id":"武侯","Pid":"成都","Children":[]},{"MyInfo":"a6","Name":null,"Id":"龙泉","Pid":"成都","Children":[]}]}]

 

2.2 调用(方式二)

//infos数据不变...

var
data = infos.ToTree("渝中");

 

data效果为(转为json方便查看):

{"MyInfo":"a1","Name":null,"Id":"渝中","Pid":"重庆","Children":[{"MyInfo":"a3","Name":null,"Id":"七星岗","Pid":"渝中","Children":[]}]}

 

完成。

 

posted @ 2020-07-10 11:01  爱恋的红尘  阅读(384)  评论(0编辑  收藏  举报