最近上班遇到这个,卡了很久,在写完后复盘了一下,决定记录下来,方便以后的查阅和温顾。
话不多说,直接贴代码:
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"))); } } }
注释写得都很清楚,对自己是一个记录,希望也可以帮到大家~
PS:楼主邮箱 tccwpl@163.com