You need to enable JavaScript to run this app. C#重构JSON对象:将父带子层级结构转为按子项聚合父项的格式
优惠活动
大模型
产品
解决方案
定价
更多

C#重构JSON对象:将父带子层级结构转为按子项聚合父项的格式

问题根因

你单ID匹配的逻辑本身没有问题,问题出在把这个全量扫描的逻辑嵌套在child ID的循环里:每匹配一个child ID就要把原始集合完整扫描一遍,整体时间复杂度是O(n²)。当数据量上来后,重复扫描的耗时、临时集合分配的内存会快速上涨,自然会出现卡顿,甚至因为内存压力过大导致进程崩溃。

最优实现方案

核心思路是做单次线性扫描的分组聚合,全程只遍历一次原始集合,就可以把所有父项按所属child完成挂载,时间复杂度降到O(n),效率会比循环匹配高一个数量级以上,完全不会出现大数据量下的卡顿问题。

步骤1:定义对应结构的实体类

先匹配原始反序列化结构和最终输出结构,避免冗余字段带来的额外内存开销:

// 对应原始JSON的父项结构
public class RawParentItem
{
    public string name { get; set; }
    public int id { get; set; }
    public RawChildItem child { get; set; }
}
// 对应原始JSON的子项结构
public class RawChildItem
{
    public string name { get; set; }
    public int id { get; set; }
}
// 对应最终输出的分组结果结构
public class GroupedChildOutput
{
    public string name { get; set; }
    public int id { get; set; }
    public List<RawParentItem> parents { get; set; }
}

步骤2:单次扫描完成分组重构

直接用LINQ的GroupBy能力,一次遍历生成目标结构,不需要嵌套循环:

// 按child的id作为分组依据,全程无额外全量查询
var result = deserializedJsonData
    .GroupBy(
        keySelector: sourceItem => sourceItem.child.id,
        resultSelector: (childId, itemsUnderChild) => 
        {
            // 同个child id下的子项元数据完全一致,直接从分组元素中取,不需要额外查询
            var childInfo = itemsUnderChild.First().child;
            return new GroupedChildOutput
            {
                name = childInfo.name,
                id = childId,
                // 分组时直接裁剪不需要的child字段,只保留父项需要的name和id
                parents = itemsUnderChild.Select(
                    i => new RawParentItem { name = i.name, id = i.id }
                ).ToList()
            };
        }
    )
    .ToList();

注意:如果实体的相等判断配置不影响分组结果,也可以直接按child对象本身作为分组key,写法会更简洁。
不要为了分组单独先枚举所有child ID列表,再循环做匹配,这种写法会完全抵消分组的效率优势。

效果说明
  • 处理10万条原始数据的耗时基本在几毫秒以内,完全不会出现之前循环遍历匹配的卡顿问题
  • 从根本上避免了重复扫描、临时集合频繁分配带来的GC压力,哪怕数据量更大也不会出现进程崩溃的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.29 23:54:04