【问题标题】:LINQ Group By using multiple criteriaLINQ 组通过使用多个条件
【发布时间】:2014-05-01 09:48:16
【问题描述】:

如何按两个不同的字段对对象列表进行分组?

例如

struct Item
{
    public string Name;
    public int Age;
    public int Score;
}

List<Item> items = new List<Item>();
items.Add(new Item(){ "Jeff", 35, 50};
items.Add(new Item(){ "Annie", 22, 45};
items.Add(new Item(){ "Pierce", 60, 90};
items.Add(new Item(){ "Pierce", 60, 10};
items.Add(new Item(){ "Abed", 28, 22};
items.Add(new Item(){ "Troy", 22, 45};
items.Add(new Item(){ "Troy", 22, 65};
items.Add(new Item(){ "Troy", 22, 80};
items.Add(new Item(){ "Troy", 21, 2};
items.Add(new Item(){ "Troy", 21, 5};

var grouped = items.GroupBy(/*Group by age then name*/);

分组然后是:

"Troy", 21, 2
"Troy", 21, 5

"Annie", 22, 45

"Troy", 22, 80
"Troy", 22, 65
"Troy", 22, 45

"Abed", 28, 22

"Jeff", 35, 50

"Pierce", 60, 90
"Pierce", 60, 10

我发现的大多数解决方案都是创建一个新的匿名类型,但这肯定会丢失“分数”字段。

如何创建原始对象的分组,其中对象按多个条件分组?

【问题讨论】:

  • 按新的匿名类型分组不会导致您丢失任何字段。您是如何尝试分组和访问“分数”字段的?
  • har07 是对的,如果您尝试过这个,您可能会发现它可以满足您的需求。如果您发现很多解决方案告诉您方法 X 有效,那么即使您认为它不起作用(尤其是如果它很快),它也可能值得尝试,因为如果它是,您可能不会发现这么多人说它错了。
  • 啊,我明白了,当我尝试时,最初并没有让我这样做。我想我之后一定是在我的 LINQ 中错误地设置了一些东西。感谢您的澄清。编辑:检查了我所做的,我认为我有一个流氓 .Select() 发生在某些括号的错误一侧,它将我的数据投影到不同的类型。
  • 不知道为什么反对票。这个问题对我来说完全有道理,而且我自己也在试图弄清楚这一点。

标签: c# .net linq list grouping


【解决方案1】:
var grouped = items.GroupBy(item => new { item.Name, item.Age });

这将产生一个IGrouping&lt;TKey, TElement&gt; 其中 TKey 是匿名类型,TElement 是 Item。 基本上,这是一个 IEnumerable 的 IEnumerable。

您可以使用双 for 循环访问它们:

foreach (var group in grouped) {
    foreach(Item item in group) {
        //...
    }
}

【讨论】:

  • 换了这个答案,因为它最详细,谢谢!
【解决方案2】:

GroupBy 方法返回IGrouping&lt;(Of &lt;(TKey, TElement&gt;)&gt;) 对象的集合,每个对象对应一个遇到的不同键。键表示IGrouping&lt;(Of &lt;(TKey, TElement&gt;)&gt;) 中每个值共有的属性,可以使用ForEach 循环访问。

  var qry = items.GroupBy(item => new { item .Age, item .Name },
           (key, group) => new
           {
               Key1 = key.Age,
               Key2 = key.Name,
               All = group.ToList()
           });

你可以用这个来检查结果:

qry.ToList().ForEach(x => x.All.ForEach(y=>Console.WriteLine("{0}, {1}, {2}",y.Name, y.Age, y.Score)));

【讨论】:

    【解决方案3】:

    使用这个:

    var grouped = items.GroupBy(item => item new{ item.Name, item.Age });
    

    您不会丢失分数字段。分组列表的子列表仍然是 Item 类型,匿名类型的对象将在每个组的 Key 属性中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-04-06
      • 1970-01-01
      • 2015-07-20
      • 2021-03-05
      • 1970-01-01
      • 2023-03-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多