list转tree,并支持搜索

  最近上班遇到这个,卡了很久,在写完后复盘了一下,决定记录下来,方便以后的查阅和温顾。

  话不多说,直接贴代码:

using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
namespace 递归
{
    public class Recursion
    {
        //测试数据
        static string _treeStr = "[{'Id':2,'Title':'第一级1','ParentId':0},{'Id':3,'Title':'第二级1','ParentId':2},{'Id':4,'Title':'第二级2','ParentId':2},{'Id':5,'Title':'第三级1','ParentId':4},{'Id':6,'Title':'第三级2','ParentId':3}]";

        /// <summary>
        /// 获取基础数据
        /// </summary>
        /// <returns></returns>
        public static List<Model> GetBaseList()
        {
            return JsonConvert.DeserializeObject<List<Model>>(_treeStr);
        }
        /// <summary>
        /// 转化成树结构
        /// </summary>
        /// <returns></returns>
        public static List<Model> GetTreeList(string searchValue)
        {
            List<Model> res = new List<Model>();
            var baseList = GetBaseList();
            if (!string.IsNullOrEmpty(searchValue))
            {
                baseList = baseList.Where(p => p.Title.Contains(searchValue)).ToList();
            }
            #region 从子级递归到所有父级
            List<Model> newlist = new List<Model>();
            newlist.AddRange(baseList);
            GetParent(GetBaseList(), baseList, newlist);
            newlist = newlist.Distinct().ToList();
            #endregion

            #region 从父级递归到所有子级
            var fisrt = newlist.Where(p => p.ParentId == 0);
            //从根开始查找、遍历
            foreach (var item in fisrt)
            {
                //parentid等于当前id的就属于子级,记录到children,然后把item放入递归方法继续查找
                item.Children = newlist.Where(p => p.ParentId == item.Id).ToList();
                GetTree(newlist, item);
                //递归完之后把item存入res,这个item已经有每个子级数据了
                res.Add(item);
            }
            #endregion

            return res;
        }
        /// <summary>
        /// 获取父级
        /// </summary>
        /// <param name="all"></param>
        /// <param name="curr"></param>
        /// <param name="res"></param>
        public static void GetParent(List<Model> all, List<Model> curr, List<Model> res)
        {
            List<Model> currlist = new List<Model>();
            foreach (var item in curr)
            {
                var temp = all.FirstOrDefault(p => p.Id == item.ParentId);
                if (temp != null)
                { 
                    //记录当前所有的父级id
                    currlist.Add(temp);
                    //每次符合条件的节点都插入最终的集合里(不同子级会有同一个父级,所以这里会重复,外侧去重即可;或者在这里判断是否哦重复再插入都行)
                    res.Add(temp);
                    //每次递归都拿当前的currlist集合去继续遍历,这样就能一直找父节点,然后一直存入res,直到tem=null,表示已经找到根了 
                    GetParent(all, currlist, res);
                }
            }
        }
        /// <summary>
        /// 获取树
        /// </summary>
        /// <param name="all"></param>
        /// <param name="obj"></param>
        public static void GetTree(List<Model> all, Model obj)
        {
            if (obj != null && obj.Children != null && obj.Children.Count > 0)
            {
                obj.Children.ForEach(p =>
                {
                    p.Children = all.Where(m => m.ParentId == p.Id).ToList();
                    GetTree(all, p);
                });
            }
        }
    }


    public class Model
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public int ParentId { get; set; }
        public List<Model> Children { get; set; }
    }
}

  调用就很简单啦,一句话:

using 递归;
using System;
using Newtonsoft.Json;
namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(JsonConvert.SerializeObject(Recursion.GetTreeList("第二级1")));
        }
    }
}

  注释写得都很清楚,对自己是一个记录,希望也可以帮到大家~ 

posted @ 2021-11-22 21:18  顾星河  阅读(71)  评论(0编辑  收藏  举报