列表项删除后的层级序号重排实现方案咨询
层级序号重排的可行实现方案
针对你提出的需求——删除扁平列表中任意层级节点后,自动重排所有节点的Order层级序号,以下是一套清晰可落地的实现方案:
核心思路
先把扁平的CMNavBarDefaultDto列表转换成树形结构,这样能清晰处理父子节点的依赖关系;删除目标节点后,再递归遍历树形结构重新生成符合规则的Order值,最后转回扁平列表即可。
1. 把扁平列表转成树形结构
因为原列表的Order是字符串格式的层级标识(比如"2.1.1"),我们需要先把它转成树形结构,方便后续操作。
首先定义一个辅助的树形节点类:
public class NavBarTreeNode { public CMNavBarDefaultDto Dto { get; set; } public List<NavBarTreeNode> Children { get; set; } = new List<NavBarTreeNode>(); }
然后实现转换逻辑:
public List<NavBarTreeNode> ConvertToTree(List<CMNavBarDefaultDto> dtoList) { var rootNodes = new List<NavBarTreeNode>(); var nodeMap = new Dictionary<string, NavBarTreeNode>(); // 用Order做键,快速查找节点 foreach (var dto in dtoList) { var treeNode = new NavBarTreeNode { Dto = dto }; nodeMap[dto.Order] = treeNode; var orderLevels = dto.Order.Split('.').Select(int.Parse).ToArray(); if (orderLevels.Length == 1) { // 根节点,直接加入根列表 rootNodes.Add(treeNode); } else { // 拼接父节点的Order(去掉最后一级) var parentOrder = string.Join(".", orderLevels.Take(orderLevels.Length - 1)); if (nodeMap.TryGetValue(parentOrder, out var parentNode)) { parentNode.Children.Add(treeNode); } } } // 根节点按原序号排序,保证顺序正确 return rootNodes.OrderBy(n => int.Parse(n.Dto.Order)).ToList(); }
2. 删除指定节点
递归遍历树形结构,找到目标ID的节点并移除(包括它的所有子节点,因为删除父项时子项也会被一并移除):
public bool RemoveNode(List<NavBarTreeNode> rootNodes, int targetId) { // 先检查根节点 var rootToRemove = rootNodes.FirstOrDefault(n => n.Dto.ID == targetId); if (rootToRemove != null) { rootNodes.Remove(rootToRemove); return true; } // 递归检查子节点 foreach (var root in rootNodes) { if (RemoveChildNode(root.Children, targetId)) { return true; } } return false; } private bool RemoveChildNode(List<NavBarTreeNode> children, int targetId) { var childToRemove = children.FirstOrDefault(n => n.Dto.ID == targetId); if (childToRemove != null) { children.Remove(childToRemove); return true; } foreach (var child in children) { if (RemoveChildNode(child.Children, targetId)) { return true; } } return false; }
3. 重新生成所有节点的Order序号
遍历树形结构,从根节点开始按层级重新分配序号:
public void RegenerateAllOrders(List<NavBarTreeNode> rootNodes) { int rootSeq = 1; foreach (var root in rootNodes) { root.Dto.Order = rootSeq.ToString(); // 递归处理子节点 RegenerateChildOrders(root, rootSeq.ToString()); rootSeq++; } } private void RegenerateChildOrders(NavBarTreeNode parentNode, string parentOrder) { int childSeq = 1; foreach (var child in parentNode.Children) { child.Dto.Order = $"{parentOrder}.{childSeq}"; RegenerateChildOrders(child, child.Dto.Order); childSeq++; } }
4. 把树形结构转回扁平列表
处理完成后,再将树形结构转回扁平的Dto列表:
public List<CMNavBarDefaultDto> ConvertToFlat(List<NavBarTreeNode> rootNodes) { var flatList = new List<CMNavBarDefaultDto>(); foreach (var node in rootNodes) { flatList.Add(node.Dto); AddChildrenToFlat(node.Children, flatList); } return flatList; } private void AddChildrenToFlat(List<NavBarTreeNode> children, List<CMNavBarDefaultDto> flatList) { foreach (var child in children) { flatList.Add(child.Dto); AddChildrenToFlat(child.Children, flatList); } }
整体执行流程
- 调用
ConvertToTree把原扁平列表转成树形结构 - 调用
RemoveNode删除目标ID的节点 - 调用
RegenerateAllOrders重新生成所有节点的Order值 - 调用
ConvertToFlat转回扁平列表,得到最终重排后的结果
额外注意事项
- 如果
Order字段存在非数字格式的异常情况,要在解析时添加异常捕获逻辑 - 若数据量较大,可以提前构建
ID到NavBarTreeNode的映射字典,提升删除节点的效率 - 所有排序操作要保证同层级节点的顺序符合业务预期
内容的提问来源于stack exchange,提问作者CodeJunkie
相关产品推荐
相关产品推荐

