在LINQ Lambda表达式中使用GroupBy和Max

时间:2013-04-07 18:25:20

标签: linq select lambda group-by max

我有一个集合,例如:

**id1, id2, value**
   1    9    12
   2    9     6
   3    11    8
   4    11   87

我想使用LINQ并获得以下结果:

**value**
   6
   87

P.S。

id1 - select MAX;
id2 - group column;

我需要以

的形式给出答案
var result = list.GroupBy(x=>x.id2).select(s=>s.value);

我希望得到你的帮助。

3 个答案:

答案 0 :(得分:26)

编辑:好的,现在我们有一套更清晰的要求(尽管还远没有写清楚),最简单的方法可能是:

var maxes = list.GroupBy(x => x.id2,
                         (key, xs) => xs.OrderByDescending(x => x.id1)
                                        .First()
                                        .value);

不幸的是,LINQ没有提供一种简单的方法来获取“具有最大值的元素”(而不是最大值本身)。我在MoreLINQ中有一个方法可以做到这一点,称为MaxBy

var maxes = list.GroupBy(x => x.id2,
                         (key, xs) => xs.MaxBy(x => x.id2).value);

原始回答(按ID2分组,取最大值)

我正在回答假设你实际上打算按id2而不是id1进行分组,而你实际上想要的结果是12和87而不是6和87。在这种情况下,你想要:

var maxes = list.GroupBy(x => x.id2, (id, xs) => xs.Max(x => x.value));

或(可能更容易理解):

var maxes = list.GroupBy(x => x.id2)
                .Select(xs => xs.Max(x => x.value));

或者:

var maxes = list.GroupBy(x => x.id2, x => x.value)
                .Select(values => values.Max());

或者:

var maxes = list.GroupBy(x => x.id2,     // Key selector
                         x => x.value,   // Element selector
                         (key, values) => values.Max()); // Result selector

甚至:

var maxes = list.GroupBy(x => x.id2)
                .Select(xs => xs.Select(x => x.value).Max());

如您所见,GroupBy有很多重载:)

或者您可以使用查询表达式:

var maxes = from x in list
            group x.value by x.id2 into values
            select values.Max();

您不应将自己局限于 查询表达式或扩展方法版本 - 了解两者都很重要,因此您可以使用最合适的内容。

答案 1 :(得分:4)

显然,OP希望Value中的Id1最多Id2

示例数据:

public class Row
{
    public int Id1;
    public int Id2;
    public int Value;
}

List<Row> rows = new List<Row>(){
    new Row(){Id1=1,Id2=9,Value=12},
    new Row(){Id1=2,Id2=9,Value=6},
    new Row(){Id1=3,Id2=11,Value=8},
    new Row(){Id1=4,Id2=11,Value=87}
};

解决方案:

List<int> res = rows.GroupBy(r => r.Id2)
                    .Select(g => g.OrderByDescending(i=>i.Id1).First().Value)
                    .ToList();

答案 2 :(得分:0)

如果它帮助其他人,我有类似的情况,除了需要返回多个记录而不是单个记录。

例如

**id1, id2, value**
   1    9    12
   2    9     6 <-
   2    9     7 <-
   3    11    8
   4    11   87 <-
   4    11   88 <-

以下四个记录作为两个记录(可枚举的枚举)的两个列表返回:

 var maxes = from x in list
            group x by x.id2 into xs
            select new {values = xs.Where(x => x.id1 == xs.Max(y => y.id1))};

 var maxes = list.GroupBy(x => x.id2,
            (key, xs) => new
            {
                values = xs.Where(x => x.id1 == xs.Max(y => y.id1))
            });