You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何按树形部门标题路径分组SubjectDto集合?

问题描述

我拥有一组部门ID,用于获取对应的Subject。我希望按照部门标题路径对这些Subject进行分组。例如,假设有Office、Room1、Room2三个部门,Office是Room1和Room2的父部门,预期分组键为"Office"、"Office/Room1"、"Office/Room2"。

现有代码仅能按Department.Title分组,无法实现层级路径分组:

var departmentsIds = _parameters.ShowSubjectsOfNestedDepartments
      ? await GetDepartmentsIdsWithNested()
      : _parameters.DepartmentIDs;
var groupedSubjects = ( await _subjectClient
      .GetByDepartmentsIds( departmentsIds )
      .Unwrap() )
      .GroupBy( subject => subject.Department.Title );

相关类定义:

public class SubjectDto
{
   public string Id { get; set; }
   public DepartmentDigestDto Department { get; set; }
}

public class DepartmentDigestDto
{
    [JsonProperty( PropertyName = "id" )]
    [JsonRequired]
    public string Id { get; set; }

    [JsonProperty( PropertyName = "title" )]
    public string Title { get; set; }

    [JsonProperty( PropertyName = "parent_department_id" )]
    public string ParentDepartmentId { get; set; }
}
解决方案

要实现按部门标题路径分组,核心是先构建每个部门的完整层级路径,再用该路径作为分组键,具体步骤如下:

  1. 收集所有相关部门数据
    首先需要获取所有涉及的部门(包括父部门)的完整信息,确保能追溯到根部门:

    // 先获取所有目标Subject
    var subjects = await _subjectClient.GetByDepartmentsIds(departmentsIds).Unwrap();
    
    // 收集所有需要查询的部门ID:包括Subject所属部门,以及它们的父部门
    var allDepartmentIds = subjects.Select(s => s.Department.Id)
                                   .Union(subjects.Select(s => s.Department.ParentDepartmentId)
                                   .Where(id => !string.IsNullOrEmpty(id)))
                                   .ToList();
    
    // 批量获取所有部门详情(如果没有批量接口,可循环调用单个查询接口)
    var allDepartments = new Dictionary<string, DepartmentDigestDto>();
    foreach (var id in allDepartmentIds)
    {
        if (!allDepartments.ContainsKey(id))
        {
            var dept = await _departmentClient.GetByIdAsync(id).Unwrap();
            allDepartments.Add(id, dept);
        }
    }
    
  2. 编写路径生成方法
    实现一个迭代方法,从当前部门向上追溯父部门,拼接出完整的标题路径:

    private string GetDepartmentPath(string departmentId, Dictionary<string, DepartmentDigestDto> allDepartments)
    {
        if (!allDepartments.TryGetValue(departmentId, out var currentDept))
        {
            return currentDept?.Title ?? string.Empty;
        }
    
        var pathParts = new List<string>();
        // 向上遍历所有父部门
        while (currentDept != null)
        {
            pathParts.Add(currentDept.Title);
            if (string.IsNullOrEmpty(currentDept.ParentDepartmentId))
                break;
            
            allDepartments.TryGetValue(currentDept.ParentDepartmentId, out currentDept);
        }
    
        // 反转得到从根到当前部门的顺序,再拼接成路径
        pathParts.Reverse();
        return string.Join("/", pathParts);
    }
    
  3. 按路径分组Subject
    调用路径生成方法,以部门标题路径作为分组键:

    var groupedSubjects = subjects.GroupBy(subject => GetDepartmentPath(subject.Department.Id, allDepartments));
    

优化建议

  • 若部门数据不频繁变动,可缓存部门的路径映射,避免重复计算和接口调用。
  • 如果有部门树结构批量查询接口,优先使用该接口,减少单次接口调用次数。

内容的提问来源于stack exchange,提问作者Anthony

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 01:27:32