Linq - orderby递减和取(1),它将返回最大项目
本文关键字:返回 项目 orderby Linq | 更新日期: 2023-09-27 18:16:29
我有这一行c#代码:
datavals
.GroupBy(x => new { x.ElementID, x.OutputTableCode})
.SelectMany(x => x
.OrderByDescending(y => y.Sequence)
.Take(1))
.ToList<TransactionValue<string>>();
思路是将列表中的项目按ElementID
和OutputTableCode
分组,然后按降序顺序对每组进行排序,并且每组只返回一个项目。(这实际上是在return语句中,因此修改后的列表将返回给调用函数。)
我的问题是,这会返回具有最大序列的项目,还是不一定是这样?在我的测试示例中,它可以,但不确定它是否得到保证。
如果它不一定返回每个组中具有最大序列的项,我如何更改查询以做到这一点?
如果sequence为空,则总是返回序列的最大值或空序列。
我们现在不知道序列的顺序,所以如果我们按desc -排序,我们将得到一个按desc排序的序列(最大值-第一个,最小值-最后一个)。执行.Take(1)
等于执行.FirstOrDefault()
,因此我们将得到序列的最大值。
如果您对.Take()
有疑问,您可以使用.FirstOrDefault()
或.First()
来检索序列的第一个值。
如果你只想获得最大值,你可以使用linq .Max()
,在这里你可以设置比较器属性,例如.Max(x => x.Sequence)
是的,您的代码将返回每组中序列最大的项。
这里是一个解释,让你更好地理解你的代码:
-
GroupBy将简单地对项目进行分组。分组将在
{ x.ElementID, x.OutputTableCode}
组合上。 - 然后,SelectMany call将:
- 首先,按
Sequence
的降序对每组进行排序 - 则
Take()
为各组Sequence
值最高的x
- 首先,按
- 最后,ToList会给你选择的x每个组作为
List<TransactionValue<string>>
。
为了简化,只需使用OrderBy
并使用LastOrDefault
获取最后一项。另外,你必须使用Select
SelectMany
datavals.GroupBy(x => new { x.ElementID, x.OutputTableCode})
.Select(x => x.OrderBy(y => y.Sequence)
.LastOrDefault()).ToList<TransactionValue<string>>();
我的问题是,这会返回具有最大序列的项目,还是不一定是这样?在我的测试示例中,它可以,但不确定它是否得到保证。
是的。它将始终返回序列最大的项。因为它是有序的,而你取的是最后一件物品,所以最后一件物品不可能没有最大Sequence
。
不如使用这个查询,因为它更易于阅读和理解。
这是你所做的。想象一下这个数组。{5,3,0,4,1,2,6}
按降序排序后,您将得到{6,5,4,3,2,1,0}
。通过只从第一项中获取1项,您将获得{6}
数组。因为它是有序的,你总是取最大的值。
在我按升序排序后,我将得到{0,1,2,3,4,5,6}
。因为这是有序的,所以最后一项的值总是最大的。我只会得到最后一项6
。
因为Take()
返回一个序列,您必须使用SelectMany
将其展开为单个项目。但是LastOrDefault
返回一个项目,所以你必须使用Select
直接选择项目。
正如@Ivan Stoev建议的那样,你也可以安全地使用Last
。阅读下面的评论