如何使用LINQ将List<MailModel>按单个收件人分组
按收件人拆分分组邮件列表的实现方法
核心实现逻辑
直接调用GroupBy只能将完全一致的To数组作为分组依据,无法拆分多收件人邮件,需要先将每封邮件按收件人展开再分组:
- 用
SelectMany方法遍历所有邮件,将单封多收件人邮件拆分为「单收件人+对应邮件」的独立条目 - 再对展开后的条目按收件人地址执行分组,直接提取邮件对象作为分组元素
代码实现
标准写法(可同时获取收件人地址和对应邮件列表)
foreach (var recipientGroup in lstMails .SelectMany(mail => mail.To.Select(recipient => new { RecipientAddress = recipient, MailItem = mail })) .GroupBy(entry => entry.RecipientAddress, entry => entry.MailItem)) { string currentRecipient = recipientGroup.Key; // 当前分组对应的收件人邮箱 List<MailModel> currentMailList = recipientGroup.ToList(); // 该收件人的专属邮件列表 // 此处编写业务逻辑 }
适配要求的ForEach(List<MailModel> list in xxx)结构写法
如果不需要在遍历中获取收件人地址,仅需要遍历每个收件人的邮件列表,可以再追加Select转换:
foreach (List<MailModel> list in lstMails .SelectMany(mail => mail.To.Select(recipient => new { RecipientAddress = recipient, MailItem = mail })) .GroupBy(entry => entry.RecipientAddress, entry => entry.MailItem) .Select(group => group.ToList())) { // 此处直接处理每个收件人的邮件列表 }
示例运行结果
对给出的5封测试邮件执行上述代码后,分组结果完全符合预期:
- nico.test@test.de:对应列表包含Mail1、Mail2
- nico.frank@test.de:对应列表包含Mail2、Mail4
- nico.jeff@test.de:对应列表包含Mail3、Mail5
- nico.star@test.de:对应列表包含Mail4
内容的提问来源于stack exchange,提问作者Nico Walsemann
相关产品推荐
相关产品推荐

