如何用LINQ将Parent与Child集合合并为Result列表?
问题描述
现有如下C#类定义及数据集合:
public class Parent { public string Region { get; set; } public string PartOfRegion { get; set; } public string Type { get; set; } public List<Child> Childs { get; set; } } public class Child { public int Year { get; set; } public int Value { get; set; } } List<Parent> listParent { get; set; } // 该列表已填充大量数据,每个Parent对象都包含对应的Child数据
需要将其转换为Result类的列表结构:
public class Result { public string Region { get; set;} public string PartOfRegion { get; set; } public string Type { get; set; } public int Year { get; set; } public int Value { get; set; } } List<Result> resultList = listParent.[LINQ]??
最终目的是能按Region、PartOfRegion、Year等维度对Value进行求和,需要用C# LINQ实现转换及后续求和操作。
解决方案
1. 将Parent列表转换为Result列表
使用SelectMany方法展开每个Parent下的Childs集合,同时将父类属性映射到Result对象中:
List<Result> resultList = listParent .SelectMany(parent => parent.Childs.Select(child => new Result { Region = parent.Region, PartOfRegion = parent.PartOfRegion, Type = parent.Type, Year = child.Year, Value = child.Value })) .ToList();
SelectMany的作用是把每个Parent对应的Childs集合“平铺”成单个序列,消除嵌套结构;- 内层
Select负责将每个Child和所属Parent的属性组合成Result实例。
2. 按指定维度对Value求和
如果需要按Region、PartOfRegion、Year分组求和(可按需调整分组维度),基于转换后的resultList使用GroupBy和Sum:
var summedResults = resultList .GroupBy(r => new { r.Region, r.PartOfRegion, r.Year // 可按需添加Type等其他分组维度 }) .Select(g => new Result { Region = g.Key.Region, PartOfRegion = g.Key.PartOfRegion, Year = g.Key.Year, Type = g.First().Type, // 若Type需参与分组,可移至GroupBy的Key中;否则取组内第一个值或自定义逻辑 Value = g.Sum(item => item.Value) }) .ToList();
GroupBy的Key为匿名类型,包含所有需要分组的维度;- 分组后通过
Sum计算每组Value总和,再映射回Result结构。
简化版:一步完成转换+分组求和
也可以跳过中间的resultList,直接在listParent上完成展开、分组、求和:
var summedResults = listParent .SelectMany(parent => parent.Childs.Select(child => new { parent.Region, parent.PartOfRegion, parent.Type, child.Year, child.Value })) .GroupBy(item => new { item.Region, item.PartOfRegion, item.Year }) .Select(g => new Result { Region = g.Key.Region, PartOfRegion = g.Key.PartOfRegion, Type = g.First().Type, Year = g.Key.Year, Value = g.Sum(i => i.Value) }) .ToList();
内容的提问来源于stack exchange,提问作者Tobias Gustafsson
相关产品推荐
相关产品推荐

