我有一个列表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。
如何重写查询以获得我想要的内容?每一个提示我都会感激不尽。 : - )
答案 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();