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

浙公网安备 33010602011771号