如何在C#中按Vendor和Type分组,拼接Month并求和NumberInvoice?
如何修改C#代码实现按Vendor和Type分组、拼接Month并求和NumberInvoice?
需求说明
- 分组规则:先按
Vendor,再按Type分组 - 列处理:拼接同组的
Month列(用逗号分隔),对NumberInvoice列求和
原代码
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApp1 { class Program { static void Main(string[] args) { var InputData = new List<Invoice>() { new Invoice{ Vendor = "Microsoft", NumberInvoice= 10, Type= "PC", Month = "1" }, new Invoice{ Vendor = "Microsoft", NumberInvoice= 10, Type= "PC", Month = "2" }, new Invoice{ Vendor = "Microsoft", NumberInvoice= 10, Type= "Surface", Month = "1" }, new Invoice{ Vendor = "Microsoft", NumberInvoice= 20, Type= "PC", Month = "1" }, new Invoice{ Vendor = "Microsoft", NumberInvoice= 20, Type= "PC", Month = "2" }, new Invoice{ Vendor = "Microsoft", NumberInvoice= 30, Type= "Surface", Month = "1" }, new Invoice{ Vendor = "IBM", NumberInvoice= 50, Type= "Network", Month = "5" }, new Invoice{ Vendor = "IBM", NumberInvoice= 60, Type= "Graphic Card", Month = "6" } }; var result = (InputData.AsEnumerable() ?? throw new InvalidOperationException()).Select( x => new { x.Vendor, x.NumberInvoice, x.Type, x.Month } ).GroupBy( y => new { y.Vendor, y.NumberInvoice, y.Type, y.Month } ) .Select( a => new Invoice { Vendor = a.Key.Vendor, NumberInvoice = a.Key.NumberInvoice, Type = a.Key.Type, Month = a.Key.Month, } ).ToList(); foreach (var item in result) { Console.WriteLine(item.Vendor+" "+ item.NumberInvoice + " " + item.Type + " " + item.Month); } Console.ReadKey(); } public class Invoice { public string Vendor { get; set; } public decimal NumberInvoice { get; set; } public string Type { get; set; } public string Month { get; set; } } } }
当前代码输出
Microsoft 10 PC 1 Microsoft 10 PC 2 Microsoft 10 Surface 1 Microsoft 20 PC 1 Microsoft 20 PC 2 Microsoft 30 Surface 1 IBM 50 Network 5 IBM 60 Graphic Card 6
期望输出
Vendor Type Month NumberInvoice ------------------------------------------------- Microsoft PC 1,2 60 Microsoft Surface 1 40 IBM Network 5 50 IBM Graphic Card 6 60
修改后的代码
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApp1 { class Program { static void Main(string[] args) { var InputData = new List<Invoice>() { new Invoice{ Vendor = "Microsoft", NumberInvoice= 10, Type= "PC", Month = "1" }, new Invoice{ Vendor = "Microsoft", NumberInvoice= 10, Type= "PC", Month = "2" }, new Invoice{ Vendor = "Microsoft", NumberInvoice= 10, Type= "Surface", Month = "1" }, new Invoice{ Vendor = "Microsoft", NumberInvoice= 20, Type= "PC", Month = "1" }, new Invoice{ Vendor = "Microsoft", NumberInvoice= 20, Type= "PC", Month = "2" }, new Invoice{ Vendor = "Microsoft", NumberInvoice= 30, Type= "Surface", Month = "1" }, new Invoice{ Vendor = "IBM", NumberInvoice= 50, Type= "Network", Month = "5" }, new Invoice{ Vendor = "IBM", NumberInvoice= 60, Type= "Graphic Card", Month = "6" } }; // 核心修改:按Vendor和Type分组,然后聚合计算 var result = InputData .GroupBy(x => new { x.Vendor, x.Type }) .Select(g => new Invoice { Vendor = g.Key.Vendor, Type = g.Key.Type, // 去重并按顺序拼接Month Month = string.Join(",", g.Select(x => x.Month).Distinct().OrderBy(m => m)), // 求和同组的NumberInvoice NumberInvoice = g.Sum(x => x.NumberInvoice) }) .ToList(); // 格式化输出实现列对齐 Console.WriteLine("{0,-12} {1,-14} {2,-8} {3,-14}", "Vendor", "Type", "Month", "NumberInvoice"); Console.WriteLine(new string('-', 50)); foreach (var item in result) { Console.WriteLine("{0,-12} {1,-14} {2,-8} {3,-14}", item.Vendor, item.Type, item.Month, item.NumberInvoice); } Console.ReadKey(); } public class Invoice { public string Vendor { get; set; } public decimal NumberInvoice { get; set; } public string Type { get; set; } public string Month { get; set; } } } }
关键修改点
- 修正分组逻辑:原代码错误地将
NumberInvoice和Month加入分组键,导致每条数据单独成组。现在仅按Vendor和Type分组,符合需求。 - 添加聚合操作:
- 用
Sum(x => x.NumberInvoice)计算同组发票数量总和 - 用
string.Join拼接同组的月份,搭配Distinct去重、OrderBy保证月份顺序
- 用
- 格式化输出:使用带宽度的格式化字符串(如
{0,-12})实现列对齐,让输出与期望格式一致。
内容的提问来源于stack exchange,提问作者MedAmin
相关产品推荐
相关产品推荐

