使用 Linq 获取集合的最后 N 个元素? [英] Using Linq to get the last N elements of a collection?

查看:30
本文介绍了使用 Linq 获取集合的最后 N 个元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定一个集合,有没有办法获取该集合的最后 N 个元素?如果框架中没有方法,那么编写扩展方法来执行此操作的最佳方法是什么?

Given a collection, is there a way to get the last N elements of that collection? If there isn't a method in the framework, what would be the best way to write an extension method to do this?

推荐答案

collection.Skip(Math.Max(0, collection.Count() - N));

这种方法保留了项目顺序而不依赖于任何排序,并且在多个 LINQ 提供程序之间具有广泛的兼容性.

This approach preserves item order without a dependency on any sorting, and has broad compatibility across several LINQ providers.

注意不要用负数调用Skip,这一点很重要.某些提供程序(例如实体框架)在提供否定参数时将产生 ArgumentException.对 Math.Max 的调用巧妙地避免了这种情况.

It is important to take care not to call Skip with a negative number. Some providers, such as the Entity Framework, will produce an ArgumentException when presented with a negative argument. The call to Math.Max avoids this neatly.

下面的类具有扩展方法的所有基本要素,它们是:静态类、静态方法以及this 关键字的使用.

The class below has all of the essentials for extension methods, which are: a static class, a static method, and use of the this keyword.

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() 操作.

Because the call to Count() can cause enumeration of certain data structures, this approach has the risk of causing two passes over the data. This isn't really a problem with most enumerables; in fact, optimizations exist already for Lists, Arrays, and even EF queries to evaluate the Count() operation in O(1) time.

但是,如果您必须使用前向可枚举并且希望避免两次传递,请考虑使用一次传递算法,例如 Lasse V. KarlsenMark Byers 描述.这两种方法都在枚举时使用临时缓冲区来保存项目,一旦找到集合的末尾,就会产生这些项目.

If, however, you must use a forward-only enumerable and would like to avoid making two passes, consider a one-pass algorithm like Lasse V. Karlsen or Mark Byers describe. Both of these approaches use a temporary buffer to hold items while enumerating, which are yielded once the end of the collection is found.

这篇关于使用 Linq 获取集合的最后 N 个元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆