本文原文出处:http://www.jucoder.com/bbs/thread-8811-0-0.html
本文和大家分享一下C#如何不使用递归实现无限层次结构的代码,我们从数据库里读取的数据都是无层次结构的二维数据,通过O/RM工具一般都可以直接转换到集合类型,之前一直使用递推将无层次的集合类型转换为有层次的集合类型。现在不用递归实现了无限层次结构。具体代码和分析如下:
定义对象,这里使用经常用到的部门对象
public class Department { /// <summary> /// 唯一标识 /// </summary> public int Id { get; set; } /// <summary> /// 部门名称 /// </summary> public string Name { get; set; } /// <summary> /// 上级部门唯一标识 /// </summary> public int ParentId { get; set; } /// <summary> /// 所有直接下一级部门 /// </summary> public IList<Department> ChildDepartments; }
准备测试用的数据集合,这里使用List
/// <summary> /// 取得测试数据 /// </summary> /// <returns></returns> public static IList<Department> GetDepartments() { var l = new List<Department>() { //ParentId = 0 表示顶层节点 new Department() {Id = 2, Name = "董事会",ParentId = 1}, new Department() {Id = 4, Name = "行政部",ParentId=1}, new Department() {Id = 5, Name = "研发部",ParentId=1}, new Department() {Id = 1, Name = "浙江**股份有限公司",ParentId = 0}, new Department() {Id = 6, Name = "营销中心",ParentId=1}, new Department() {Id = 7, Name = "人力资源部",ParentId=4}, new Department() {Id = 8, Name = "采购部",ParentId =4}, new Department() {Id = 3, Name = "总经理办公室",ParentId =1}, new Department() {Id = 9, Name = ".Net技术研发部",ParentId =5}, new Department() {Id = 10, Name = "销售一部",ParentId =6}, new Department() {Id = 11, Name = "java技术研发部",ParentId =5 }, new Department() {Id = 12, Name = "销售二部",ParentId= 6}, new Department() {Id = 13, Name = "第一项目组",ParentId=9}, new Department() {Id = 14, Name = "华东市场部",ParentId=12}, new Department() {Id = 15, Name = "华南市场部",ParentId=12}, new Department() {Id = 16, Name = "第二项目组" ,ParentId = 9}, new Department() {Id = 17, Name = "上海**集团",ParentId = 0} }; return l; }
上面的List集合是没有层次结构的,实际项目中一般来源于数据库的二维表。
下面将List转换成具有层次结构的List
public static IList<Department> ToTree(IList<Department> ds) { //定义字典类型,将List转换成字典类型,集合中的元素个数是相同的 var dic = new Dictionary<int, Department>(ds.Count); foreach (var department in ds) { dic.Add(department.Id,department); } //通过一次遍历集合,转换成具有层次结构的类型 foreach (var department in dic.Values) { if(dic.ContainsKey(department.ParentId)) { if (dic[department.ParentId].ChildDepartments ==null) dic[department.ParentId].ChildDepartments = new List<Department>(); dic[department.ParentId].ChildDepartments.Add(department); } } //仅仅选择最顶层节点返回 return dic.Values.Where(t => t.ParentId == 0).ToList(); }
以下是测试代码
var t = Util.ToTree(Util.GetDepartments());
通过调试可以清楚看到当前的List已经具有层次结构了,该集合中只有两个顶层节点的元素了。