首页 / C#开发 / 正文

C#/.NET应用程序编程开发中如何使用LINQ获取泛型集合的最后N个元素?

1911 1 发布于: 2019-07-08 读完约需8分钟

问题描述

C#/.NET应用程序编程开发中,假如当前有一个泛型集合,如何使用LINQ获取这个泛型集合的最后N个元素?

方案一

使用LINQ的扩展方法Skip(),如下:

登录后复制
collection.Skip(Math.Max(0, collection.Count() - N));

为了重复使用,我们也可以将其他封装成一个静态扩展方法,如下:

登录后复制
public static class MiscExtensions { public static IEnumerable<T> TakeLast<T>(this IEnumerable<T> source, int N) { return source.Skip(Math.Max(0, source.Count() - N)); } }

调用示例:

登录后复制
var collection = new List<T>(); var lastElements = collection.TakeLast(5);

方案二

使用LINQ的扩展方法Reverse()将列表反转,再使用Take()方法取前N个元素,最后再将取出的子集合进行Reverse()即可,扩展方法如下:

登录后复制
public static IEnumerable<T> TakeLast<T>(this IEnumerable<T> coll, int N) { return coll.Reverse().Take(N).Reverse(); }

方案三

封装一个不使用LINQ的扩展方法,如下:

登录后复制
public static class Extensions { public static IEnumerable<T> TakeLast<T>(this IEnumerable<T> collection, int n) { if (collection == null) throw new ArgumentNullException("collection"); if (n < 0) throw new ArgumentOutOfRangeException("n", "n must be 0 or greater"); LinkedList<T> temp = new LinkedList<T>(); foreach (var value in collection) { temp.AddLast(value); if (temp.Count > n) temp.RemoveFirst(); } return temp; } }

调用示例:

登录后复制
IEnumerable<int> sequence = Enumerable.Range(1, 10000); IEnumerable<int> last10 = sequence.TakeLast(10);

方案四

另一个不使用LINQ封装的扩展方法,如下:

登录后复制
public static class TakeLastExtension { public static IEnumerable<T> TakeLast<T>(this IEnumerable<T> source, int takeCount) { if (source == null) { throw new ArgumentNullException("source"); } if (takeCount < 0) { throw new ArgumentOutOfRangeException("takeCount", "must not be negative"); } if (takeCount == 0) { yield break; } T[] result = new T[takeCount]; int i = 0; int sourceCount = 0; foreach (T element in source) { result[i] = element; i = (i + 1) % takeCount; sourceCount++; } if (sourceCount < takeCount) { takeCount = sourceCount; i = 0; } for (int j = 0; j < takeCount; ++j) { yield return result[(i + j) % takeCount]; } } }

调用示例:

登录后复制
List<int> l = new List<int> {4, 6, 3, 6, 2, 5, 7}; List<int> lastElements = l.TakeLast(3).ToList();

方案五

使用LINQ的扩展方法SkipWhile,如下:

登录后复制
public static IEnumerable<T> TakeLastN<T>(this IEnumerable<T> source, int n) { if (source == null) throw new ArgumentNullException("Source cannot be null"); int goldenIndex = source.Count() - n; return source.SkipWhile((val, index) => index < goldenIndex); }

版权声明:本作品系原创,版权归码友网所有,如未经许可,禁止任何形式转载,违者必究。

上一篇: [SQL Server]SQL Server数据库中如何使用SQL语句删除指定数据库所有的数据表、视图、存储过程、触发器、主键、外键、约束以及所有的依赖关系等等?

下一篇: C#/.NET应用程序编程开发中使用AutoMapper时如何忽略某个或某些属性的映射?

本文永久链接码友网 » C#/.NET应用程序编程开发中如何使用LINQ获取泛型集合的最后N个元素?

分享扩散:

发表评论

登录用户才能发表评论, 请 登 录 或者 注册