给定People与Relation类,如何按层级从资深到次要排序People对象?
基于层级对People对象排序的实现方案
嘿,这个需求我之前处理组织架构类业务时碰到过,咱们一步步拆解来搞定它:
首先得明确核心逻辑:你说的「层级最深=最资深」,我默认是指在上下级链里越往下(比如下属的下属)层级越深,也就越资深——如果你的业务里「资深」是指上级(层级更浅),那最后排序时改成升序就行,这个后面再说。
1. 先把关联关系转成方便使用的映射结构
咱们手里的Relation是两两关联的原始数据,直接用不太方便,得先转成两个字典:
- 一个
上级映射表:key是人员的externalId,value是他直属上级的externalId,方便快速查询谁是谁的领导 - 一个
下属映射表:key是上级的externalId,value是他所有直属下属的externalId列表,方便批量处理下属
用C#实现的示例代码如下:
// 假设已获取人员列表peopleList和关联列表relationList var parentMap = new Dictionary<string, string>(); var childrenMap = new Dictionary<string, List<string>>(); foreach (var relation in relationList) { // 这里假设relation.type=1代表「source是dest的上级」,请根据实际业务调整判断条件! if (relation.type == 1) { // 为下属记录直属上级 parentMap[relation.destExternalId] = relation.sourceExternalId; // 为上级记录直属下属 if (!childrenMap.ContainsKey(relation.sourceExternalId)) { childrenMap[relation.sourceExternalId] = new List<string>(); } childrenMap[relation.sourceExternalId].Add(relation.destExternalId); } }
2. 计算每个人的层级深度
接下来要算出每个人员的层级深度:
- 没有上级的顶层人员(比如公司老板)深度设为0
- 每个下属的深度 = 他直属上级的深度 + 1
- 深度数值越大,代表层级越深,也就是越资深
这里用广度优先遍历(BFS)来计算,避免递归可能出现的栈溢出问题:
var depthMap = new Dictionary<string, int>(); var queue = new Queue<(string externalId, int depth)>(); // 先找出所有顶层人员(无上级的人员) var topLevelPeople = peopleList.Where(p => !parentMap.ContainsKey(p.externalId)).ToList(); foreach (var person in topLevelPeople) { depthMap[person.externalId] = 0; queue.Enqueue((person.externalId, 0)); } // 遍历所有人员,计算层级深度 while (queue.Count > 0) { var current = queue.Dequeue(); // 如果当前人员有下属,为下属计算深度 if (childrenMap.TryGetValue(current.externalId, out var children)) { foreach (var childId in children) { var childDepth = current.depth + 1; depthMap[childId] = childDepth; queue.Enqueue((childId, childDepth)); } } }
3. 按层级深度降序排序
现在每个人的层级深度都已明确,直接对人员列表按深度从大到小排序即可;如果深度相同,可以添加次要排序条件(比如id、姓名等):
var sortedPeople = peopleList .OrderByDescending(p => depthMap[p.externalId]) // 核心规则:深度越大越靠前(最资深) .ThenBy(p => p.id) // 深度相同时按id排序,可根据需求调整 .ToList();
需要注意的特殊情况
- 如果业务定义「资深」为上级(层级越浅越资深),只需把
OrderByDescending改成OrderBy即可 - 如果存在循环关联(比如A是B的上级,B又是A的上级),需要在遍历过程中添加循环检测,避免死循环
- 无任何关联的人员深度为0,会和顶层人员排在同一层级
内容的提问来源于stack exchange,提问作者Drag and Drop
相关产品推荐
相关产品推荐

