给定一个集合,有没有办法获取该集合的最后 N 个元素?如果框架中没有方法,那么编写扩展方法来执行此操作的最佳方法是什么?
最佳答案
collection.Skip(Math.Max(0, collection.Count() - N));
这种方法保留了项目顺序而不依赖于任何排序,并且在多个 LINQ 提供程序之间具有广泛的兼容性。
注意不要用负数调用 Skip
,这一点很重要。某些提供程序(例如 Entity Framework )在出现否定参数时会产生 ArgumentException。对 Math.Max
的调用巧妙地避免了这种情况。
下面的类具有扩展方法的所有要素,它们是:静态类、静态方法和 this
关键字的使用。
public static class MiscExtensions
{
// Ex: collection.TakeLast(5);
public static IEnumerable<T> TakeLast<T>(this IEnumerable<T> source, int N)
{
return source.Skip(Math.Max(0, source.Count() - N));
}
}
关于性能的简要说明:
因为调用 Count()
会导致某些数据结构的枚举,这种方法有导致两次传递数据的风险。对于大多数可枚举对象来说,这并不是真正的问题;事实上,列表、数组甚至 EF 查询的优化已经存在,可以在 O(1) 时间内评估 Count()
操作。
但是,如果您必须使用仅向前的可枚举并且希望避免进行两次传递,请考虑像 Lasse V. Karlsen 这样的一次传递算法。或 Mark Byers描述。这两种方法都在枚举时使用临时缓冲区来保存项目,一旦找到集合的末尾就会产生这些项目。
关于c# - 使用 Linq 获取集合的最后 N 个元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3453274/