c# - 使用 Linq 获取集合的最后 N 个元素?

标签 c# linq

给定一个集合,有没有办法获取该集合的最后 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/

相关文章:

c# - Dictionary KeyNotFoundException 即使 Key 存在

c# - 使用 Linq,按某些属性对对象进行排序并选择前 2 个对象

c# - 在 LINQ 中编写 SQL 查询

c# - 包含 CheckBoxList 的 ListView - 所选项目未显示为已选中

c# - 使用LINQ的 "into"关键字进行分组连接不返回集合

java - C# 和 Java 中的 AES 加密文件

c# - 从 AR 相机截屏后更新 Android Gallery?

C# 将一个按钮类调用到另一个类中

c# - 通过 HTTPS 使用 Web 服务时抛出 System.Net.WebException

c# - 通用可变参数