LINQ – 选择每组最大属性值的记录

我有一个这样的数据集:

GroupName GroupValue MemberName MemberValue 'Group1' 1 'Member1' 1 'Group1' 1 'Member2' 2 'Group2' 2 'Member3' 3 'Group2' 2 'Member4' 2 'Group3' 2 'Member5' 4 'Group3' 2 'Member6' 1 

我想要选择的是每个GroupName具有最大MemberValue的行,但仅适用于具有最大GroupValue GroupName ,并将它们传递给委托函数。 像这样:

 'Group2' 2 'Member3' 3 'Group3' 2 'Member5' 4 

到目前为止我已经尝试过这种格式……

 data.Where(maxGroupValue => maxGroupValue.GroupValue == data.Max(groupValue => groupValue.GroupValue)) .Select(FunctionThatTakesData) 

……但这只是给了我Group2和Group3的每个成员。 我已经尝试在Select() GroupBy()之前放置一个GroupBy() ,但是将输出转换为IGrouping所以FunctionThatTakesData()不知道该如何处理它,我不能再做另一个Where()仅过滤掉最大的MemberValue

我该怎么做才能使这个数据集正确过滤并传递到我的函数中?

您可以使用以下Linq执行此操作。

 var results = data.GroupBy(r = r.GroupValue) .OrderByDescending(g => g.Key) .FirstOrDefault() ?.GroupBy(r => r.GroupName) .Select(g => g.OrderByDescending(r => r.MemberValue).First()); 

首先,您必须对GroupValue进行分组,然后按Key (即GroupValue )按降序对组进行排序,并取第一个。 现在,您拥有最大GroupValue所有行。 然后,您对GroupName上的那些进行分组,并从这些组按降序对MemberValue进行排序,并使用First行获取具有最大MemberValue每个GroupName组中的行。 我还在使用C#6 null条件运算符?.FirstOrDefault之后, data为空。 如果您没有使用C#6,那么您需要预先处理该案例,而您只需使用First

所以基本上你想要的是将你的数据元素分成具有相同GroupName值的组。 从您想要获取一个元素的每个组中,即属性为MemberValue值最大的MemberValue

每当你有一系列项目,并且你想根据序列中项目的一个或多个属性的值将这个序列分成组时,你使用Enumerable.GroupBy

‘GroupBy’有一个输入参数,这个函数可以选择要在您决定要在哪个组中显示项目时要比较的项目属性。

您希望将序列划分为组,其中组中的所有元素具有相同的GroupName

 var groups = mySequence.GroupBy(element => element.GroupName); 

它的作用是,它从mySequence中的每个元素获取属性GroupName,并将此元素放入一组具有此GroupName值的元素中。

使用示例数据,您将拥有三个组:

  • 具有GroupName ==“Group1”的所有元素的组。 序列的前两个元素将在此组中
    • 具有GroupName ==“Group2”的所有元素的组。 序列的第三和第四个元素将在此组中
    • 具有GroupName ==“Group3”的所有元素的组。 序列的最后两个元素将在此组中

每个组都有一个属性Key,包含您的选择值。 此密钥标识该组,并保证在您的组集合中是唯一的。 所以你将拥有一个Key ==“Group1”的组,一个Key ==“Group2”的组等。

除了Key ,每个组都是组中元素的序列(注意:组一个可枚举的序列,而不是一个可枚举的序列。

第二步是采用MemberValue值最大的组中的元素。 为此,您可以按属性MemberValue的降序值对组中的元素进行排序,然后取第一个。

 var myResult = mySequence.GroupBy(element => element.GroupName) // intermediate result: groups where all elements have the same GroupName .Select(group => group.OrderByDescending(groupElement => groupElement.MemberValue) // intermediate result: groups where all elements are ordered in descending memberValue .First(); 

结果:从降序memberValue排序的每个组中,取第一个元素,该元素应该是最大的元素。

如果您只希望元素具有memberValue的最大值,则订购完整组的效率不高。 可以在StackOverflow上找到答案