LINQ - 选择每组具有最大属性值的记录

问题描述 投票:2回答:2

我有一个这样的数据集:

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

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

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

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

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

......但这只是给了我Group2和Group3的每个成员。我已经尝试在GroupBy()之前放置一个Select(),但是这会将输出变成IGrouping<string, DataType>所以FunctionThatTakesData()不知道该怎么做,我不能做另一个Where()来过滤掉最大的MemberValues。

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

c# .net linq group-by
2个回答
5
投票

您可以使用以下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行以获得每个GroupName组中最大MemberValue的行。另外我在?.之后使用C#6空条件运算符FirstOrDefault,以防data为空。如果您没有使用C#6,那么您需要预先处理该案例,而您可以使用First代替。


0
投票

所以基本上你想要的是将你的数据元素分成具有相同GroupName值的组。从每个组中你想要一个元素,即属性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的最大值,则订购完整组的效率不高。 qzxswpoi可以找到答案

© www.soinside.com 2019 - 2024. All rights reserved.