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

如何在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; }
        }
    }
}

关键修改点

  1. 修正分组逻辑:原代码错误地将NumberInvoice和Month加入分组键,导致每条数据单独成组。现在仅按Vendor和Type分组,符合需求。
  2. 添加聚合操作:
    • 用Sum(x => x.NumberInvoice)计算同组发票数量总和
    • 用string.Join拼接同组的月份,搭配Distinct去重、OrderBy保证月份顺序
  3. 格式化输出:使用带宽度的格式化字符串(如{0,-12})实现列对齐,让输出与期望格式一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 09:40:30