如何在C#中合并List<T>指定部分并实现求和?
问题描述
从数据库获取零件数据集,提取5个参数(GroupName、ProfileType、MaterialType、Profile、Weight)构建元组列表,当前代码生成的表格中,存在**ProfileType、MaterialType、Profile**这三个属性相同的行,需要将这些行合并为一行,并对Weight求和,实现合并后的表格效果。
原代码如下:
List<Tuple<string, string, string, string, double>> ListOfParts = new List<Tuple<string, string, string, string, double>>(); while (AllParts.MoveNext()) ///where AllParts is the set of all parts, which I've got from database { foreach (PartClass myPart in AllParts) ///where myPart is the each part of all parts from database { string GroupName = ///... got it from database string ProfileType = ///... got it from database string MaterialType = ///... got it from database string Profile = ///... got it from database double Weight = ///... got it from database ListOfParts.Add(new Tuple<string, string, string, string, double>(GroupName, ProfileType, MaterialType, Profile, Weight)); } } ListOfParts.Sort(); WriteList(ListOfParts); ///transfer my ListOfParts to another code block void WriteList(List<Tuple<string, string, string, string, double>> ListOfParts) { for (int i = 0; i < ListOfParts.Count; i++) { ///here is the code to draw a table lines and values of those 5 parameters } }
初始表格状态:表格包含5列,分别是GroupName、ProfileType、MaterialType、Profile、Weight,存在多行ProfileType、MaterialType、Profile完全相同的记录,每行对应单独的Weight值。
目标表格状态:将所有ProfileType、MaterialType、Profile相同的行合并为一行,保留对应的GroupName,Weight列显示这些行的Weight总和。
解决方案
方式一:使用LINQ分组求和(推荐)
在生成ListOfParts后、调用WriteList前,先对列表进行分组处理,按**ProfileType、MaterialType、Profile**分组,对每组的Weight求和,同时保留GroupName(假设同一组内GroupName一致,若不一致可根据需求选择保留第一个或拼接)。
修改代码如下:
// 原代码生成ListOfParts后,替换原来的Sort和WriteList调用 var mergedParts = ListOfParts .GroupBy(t => new { t.Item2, t.Item3, t.Item4 }) // 按ProfileType(Item2)、MaterialType(Item3)、Profile(Item4)分组 .Select(g => new Tuple<string, string, string, string, double>( g.First().Item1, // 取分组内第一个元素的GroupName,若需要拼接可改为string.Join(",", g.Select(t=>t.Item1)) g.Key.Item2, g.Key.Item3, g.Key.Item4, g.Sum(t => t.Item5) // 对分组内的Weight求和 )) .ToList(); mergedParts.Sort(); // 按元组默认规则排序 WriteList(mergedParts);
方式二:在WriteList方法中处理合并输出
如果不想修改原列表,可以在绘制表格时,手动遍历并合并相同分组的行:
void WriteList(List<Tuple<string, string, string, string, double>> ListOfParts) { if (ListOfParts.Count == 0) return; // 先排序确保相同分组的行连续(原代码已经Sort过,这里可省略,保险起见保留) var sortedParts = ListOfParts.OrderBy(t => t.Item2).ThenBy(t => t.Item3).ThenBy(t => t.Item4).ToList(); int i = 0; while (i < sortedParts.Count) { var current = sortedParts[i]; string profileType = current.Item2; string materialType = current.Item3; string profile = current.Item4; // 统计同一分组的总重量 double totalWeight = 0; int j = i; while (j < sortedParts.Count && sortedParts[j].Item2 == profileType && sortedParts[j].Item3 == materialType && sortedParts[j].Item4 == profile) { totalWeight += sortedParts[j].Item5; j++; } // 绘制合并后的行:GroupName用current.Item1,其他取分组值,Weight为总和 // 替换成你原来的绘制代码 DrawTableRow(current.Item1, profileType, materialType, profile, totalWeight); i = j; // 跳到下一个分组 } }
注意事项
- 如果同一分组内的
GroupName不一致,需根据业务需求处理:比如拼接所有GroupName、保留第一个值,或取统一标识。 - 元组的
Item1到Item5分别对应GroupName、ProfileType、MaterialType、Profile、Weight,注意不要混淆顺序。
内容的提问来源于stack exchange,提问作者Стас Петров
相关产品推荐
相关产品推荐

