No Max()适用:序列不包含任何元素

时间:2011-09-15 11:00:52

标签: c#

我有一个列表list,其中的项目就像这样

ElementA: Number=1, Version=1
ElementB: Number=1, Version=2 
ElementC: Number=1, Version=3 <-
ElementD: Number=2, Version=1
ElementE: Number=2, Version=2 <-
ElementF: Number=3, Version=1 <-

我希望选择组中Version最高且项目具有相同Number的所有项目。 (见上面的箭头。)

我想对此使用查询,所以我试过这个:

var result = from a in list where a.Version >=
            (from b in list where b.Number == a.Number && b != a select b.Version).Max() select a;

如果每个具有相同Number的项目组至少包含2个元素,则此工作正常,但如果内部查询不包含任何元素,则会抛出InvalidOperationException。

如何重写查询以获得我想要的内容?每一个提示我都会感激不尽。 : - )

4 个答案:

答案 0 :(得分:4)

这应该可以解决问题,但是如果不自行复制数据我无法测试它:

var result = 
     list.GroupBy(x => x.Number)
         .Select(gr => 
                    gr.OrderByDescending(x => x.Version)
                      .First());

正如Henrik注意到这只会得到一个项目 - 我没有看到获得更多项目的原因,因为项目似乎只包含两个字段,但这很容易被处理 - 只需为该版本添加另一个组:

var result = 
     list.GroupBy(x => x.Number)
         .Select(gr =>
                    gr.GroupBy(x => x.Version)
                      .OrderByDescending(gr2 => gr2.Key)
                      .Select(gr => gr.ToArray()));

这应该导致枚举具有最大版本的Arrays - 但我再次无法测试,因此可能存在语法或语义错误,但缩进应该清晰,错误很容易删除。

答案 1 :(得分:2)

听起来我想先按号码分组,然后按版本排序并选择最后一个条目:

var result = from entry in list
             group entry by entry.Number into g
             select g.OrderBy(x => x.Version).Last();

或者为了避免实际订购,如果您不介意创建新条目:

var result = from entry in list
             group entry by entry.Number into g
             select new Entry { Number = g.Key,
                                Version = g.Max(x => x.Version) };

编辑:根据Carsten的方法使用OrderByDescending避免必须迭代到最后一个条目:

var result = from entry in list
             group entry by entry.Number into g
             select g.OrderByDescending(x => x.Version).First();

答案 2 :(得分:0)

只需删除&& b != a部分。

答案 3 :(得分:0)

喜欢这个吗?

var result = from e in elements
             group e by e.Number into eGroup
             select eGroup.OrderByDescending(x => x.Version).First();