1.源数据
[{"Id":1,"Name":"四川","PId":0},{"Id":2,"Name":"成都","PId":1},{"Id":3,"Name":"自贡","PId":1},{"Id":4,"Name":"绵阳","PId":1},{"Id":5,"Name":"成都区-0","PId":2},{"Id":6,"Name":"成都区-1","PId":2},{"Id":7,"Name":"成都区-2","PId":2},{"Id":8,"Name":"成都区-3","PId":2},{"Id":9,"Name":"成都区-4","PId":2},{"Id":10,"Name":"成都区-5","PId":2},{"Id":11,"Name":"成都区-6","PId":2},{"Id":12,"Name":"成都区-7","PId":2},{"Id":13,"Name":"成都区-8","PId":2},{"Id":14,"Name":"成都区-9","PId":2},{"Id":15,"Name":"自贡区-0","PId":3},{"Id":16,"Name":"自贡区-1","PId":3},{"Id":17,"Name":"自贡区-2","PId":3},{"Id":18,"Name":"自贡区-3","PId":3},{"Id":19,"Name":"自贡区-4","PId":3},{"Id":20,"Name":"自贡区-5","PId":3},{"Id":21,"Name":"自贡区-6","PId":3},{"Id":22,"Name":"自贡区-7","PId":3},{"Id":23,"Name":"自贡区-8","PId":3},{"Id":24,"Name":"自贡区-9","PId":3},{"Id":25,"Name":"绵阳区-0","PId":4},{"Id":26,"Name":"绵阳区-1","PId":4},{"Id":27,"Name":"绵阳区-2","PId":4},{"Id":28,"Name":"绵阳区-3","PId":4},{"Id":29,"Name":"绵阳区-4","PId":4},{"Id":30,"Name":"绵阳区-5","PId":4},{"Id":31,"Name":"绵阳区-6","PId":4},{"Id":32,"Name":"绵阳区-7","PId":4},{"Id":33,"Name":"绵阳区-8","PId":4},{"Id":34,"Name":"绵阳区-9","PId":4}]
2.树型结构
{
"id":2,
"name":"",
"pId":1,
"nodes":[]
}
//元数据
public class Area
{
public int Id { get; set; }
public string Name { get; set; } = "";
public int PId { get; set; }
}
//树结构
public class Area_Tree
{
public int Id { get; set; }
public string Name { get; set; } = "";
public int PId { get; set; }
public List<Area_Tree> Nodes { get; set; } = new List<Area_Tree>();
}
3.需求
3.1.获得某个节点的树型结构
3.1.1.需求分析
此种需求是最简单的设计,只需要一直递归就行
3.1.2.代码实现
private static Area_Tree GetTree(List<Area_Tree> list, int Id)
{
var data = list.Where(x => x.Id == Id).Single();
var trees = list.Where(x => x.PId == Id)
.ToList();
//说明找到最底层了
if (trees.Count == 0)
return data;
trees.ForEach(x =>
{
//寻找子节点
GetTree(list, x.Id, ids, nodeids);
});
data.Nodes = trees;
return data;
}
3.2.获得某个节点的所有父级树型结构
3.2.1.需求分析
此需求,分两步走
- 创建一个集合来存储PId
- 通过递归一直追查PId,直到PId=0(此处的0是我设定的如果没有上级这PId=0)
- 找到最上级后,就回到了第一种方案了
3.2.2.代码实现
class Program{
static main(){
List<Area_Tree> list=[某个数据源];
/**{
"id": 34,
"name": "绵阳区-9",
"pId": 4
}
**/
int id=34;
Area_Tree tree= GetTree_V2(list, id);
}
//找到父节点再找节点
private static Area_Tree GetTree_V2(List<Area_Tree> list, int id, List<int> ids = null){
if (ids == null)
ids = new List<int>();
ids.Add(id);
var obj = list.Single(x => x.Id == id);
if (obj.PId != 0)
obj = GetTree_V2(list, obj.PId, ids);
else
obj.Nodes.Add(GetTree(list, obj.Id, ids));
return obj;
}
//找到当前节点以及子节点
private static Area_Tree GetTree(List<Area_Tree> list, int Id, List<int> ids = null)
{
var data = list.Where(x => x.Id == Id).Single();
var trees = list.Where(x => x.PId == Id)
.WhereIF(!ids.IsNullOrCountZore(), x => ids.Contains(x.Id))
.ToList();
if (trees.Count == 0)
return data;
trees.ForEach(x =>
{
GetTree(list, x.Id, ids);
});
data.Nodes = trees;
return data;
}
}
3.3.获得某个节点的父级与子级树型结构
3.3.1.需求分析
先递归获得所有子节点,放入节点集合。再将此节点ID集合带入递归父节点,再将父节点Id放入节点集合中,递归上级到最高级,开始按照正常流程递归,但只是需要限定一下递归出来的下级必须包含再节点ID集合中.
3.3.2.代码实现
private static Area_Tree GetTree_V2(List<Area_Tree> list, int id, List<int> ids = null)
{
if (ids == null)
ids = new List<int>();
ids.Add(id);
var obj = list.Single(x => x.Id == id);
if (obj.PId != 0)
obj = GetTree_V2(list, obj.PId, ids);
else
obj.Nodes.Add(GetTree(list, obj.Id, ids));
return obj;
}
private static Area_Tree GetTree(List<Area_Tree> list, int Id, List<int> ids = null, List<int> nodeids = null)
{
if (nodeids == null)
nodeids = new List<int>();
var data = list.Where(x => x.Id == Id).Single();
var trees = list.Where(x => x.PId == Id)
.WhereIF(!ids.IsNullOrCountZore(), x => ids.Contains(x.Id))
.ToList();
nodeids.AddRange(trees.Select(x => x.Id));
if (trees.Count == 0)
return data;
trees.ForEach(x =>
{
GetTree(list, x.Id, ids, nodeids);
});
data.Nodes = trees;
return data;
}
int main(){
List<Area_Tree> list=[某个数据源];
/**
{
"id": 34,
"name": "绵阳区-9",
"pId": 4
}
**/
int id=4;
var nodelist = new List<int>() { };
//此方法主要是为了获得所有子节点
Area_Tree buttontree = GetTree(areas, id, null, nodelist);
//此方法开始正式组装树
Area_Tree tree = GetTree_V2(areas, Id, nodelist);
}