Linq Group by 并获取返回所有列的特定字符串规则的所有值

Posted

技术标签:

【中文标题】Linq Group by 并获取返回所有列的特定字符串规则的所有值【英文标题】:Linq Group by and get all values for a specific string rule returning all columns 【发布时间】:2022-01-06 16:07:58 【问题描述】:

我遇到了一个问题,所以我会提供所有背景信息。

我从一个通用字符串列表中获得了 2 项考试,每项考试都有相同的电子邮件和通过的是或否。

我的收获如何?

var list = new List<string>();

对于每个字符串,我得到一个模型位置 0 到 13 之间的记录,工作正常

List<Participants> p = new List<Participants>();
for (var i = 0; i < list.Count; i += 13)

    p.Add(new Participants()
    
        LastName = list[0 + i],
        FirstName = list[1 + i],
        AddressType = list[2 + i],
        Email = list[3 + i],
        Company = list[4 + i],
        Phone = list[5 + i],
        Street = list[6 + i],
        ZipCode = list[7 + i],
        City = list[8 + i],
        IsSiemens = isSiemens,
        Country = list[9 + i],
        Percent = list[10 + i],
        Points = list[11 + i],
        Passed = list[12 + i],
    );

然后这行得通,因为我知道我只有 2 个部分(考试)

var distinctList = p.GroupBy(s => s.Email).Select(s => s.First()).ToList();

var distinctList = p.GroupBy(s => s.Email).Select(s => s.Last()).ToList();

现在的问题是我可以有更多的考试,我想动态地做,所以对于每封电子邮件我都想知道是否全部通过。换句话说,通过Email 全部Passed 对模型进行分组必须是肯定的,然后我知道对于此认证,特定电子邮件已成功完成。

我被屏蔽了!!

【问题讨论】:

【参考方案1】:

换句话说,通过电子邮件对模型进行分组全部通过必须是肯定的,然后我知道对于此认证,特定电子邮件已成功完成。

听起来,最基本的

var listOfEmailsThatPassed = p
  .GroupBy(s => s.Email)
  .Where(g => g.All(pt => pt.Passed == "Yes"))
  .Select(g => g.Key)
  .ToList()

你没有说 Passed 是什么类型;我假设是字符串,但如果它是布尔值g.All(pt =&gt; pt.Passed)

分组可能很难理解,但可以把它想象成一个参与者列表列表,你有一个.Where(,它作用于分组g,这是一个参与者列表,所以你希望 All 分组中的参与者 pt 已经通过

对于参与者列表(我已跳过课程名称等细节):

   john@a.com Yes
   john@a.com Yes
   fred@b.com Yes
   fred@b.com No

分组后的样子

   g => g.Key: john@a.com   g: [ john@a.com Yes, john@a.com Yes] 
   g => g.Key: fred@b.com   g: [ fred@b.com Yes, fred@b.com No]

因此,您可以使用 Where 对这两行中的每一行进行操作,g 本身就是所有共享相同密钥(电子邮件)的参与者的(子)列表,因此您要求 g.All(participant =&gt; some predicate).. 和这就是您测试 Passed == "Yes" 作为谓词的地方。如果有人是Passed == "No",那么All 将返回falseWhere 将从结果中排除他们

去哪儿之后的样子:

   g => g.Key: john@a.com   g: [ john@a.com Yes, john@a.com Yes] 
   

它仍然是一个分组,所以也许你必须选择电子邮件:

.Select(g => g.Key).ToList()

这将产生List&lt;string&gt; 已通过的电子邮件

【讨论】:

好点,我可以完成这项工作,但我需要整个模型,所以我必须在 list 中重复 foreach,如果包含已过滤的 List&lt;string&gt;,则放置一个标志。正在工作,但说实话,代码真的很糟糕。我可以提出解决方案,但会带来非常糟糕的声誉:) 我没听懂你在说什么。当您“需要整个模型”时,这是什么意思?我的代码中没有foreach .. 你是说你不想要一个字符串列表,你想要一个参与者列表吗? 是的,正是参与者类型的列表

以上是关于Linq Group by 并获取返回所有列的特定字符串规则的所有值的主要内容,如果未能解决你的问题,请参考以下文章

无论如何,他们是不是要向使用 group by 返回特定列的最新行的查询添加连接

应用 group_by 并汇总数据,同时保留所有列的信息

C# Linq to SQL — Group by

3-实体数据模型与LINQ-分组

带有表连接、case 语句、计数、group by 子句的 Linq 查询

从 GROUP BY 中获取具有 NULL 列的行