Stackoverflow 珠玑:用于分组的 LINQ 扩展方法
2017-04-03 02:24
555 查看
从 stackoverflow.com 上抄来的,将 IEnumerable 中的元素进行切分的方法,无动态内存分配,地球上最快的实现:
两个方法以不同的形式对 IEnumerable 集合中的元素进行分组,非常有用,而且没有容器操作等动态内存分配,不可能再快了。
public static class LinqExtensions { /// <summary> /// 将 source 中的条目按照 partitionSize 指定的每组数量进行分组 /// http://stackoverflow.com/questions/3773403/linq-partition-list-into-lists-of-8-members /// </summary> /// <typeparam name="T"></typeparam> /// <param name="source"></param> /// <param name="partitionSize"></param> /// <returns></returns> public static IEnumerable<IEnumerable<T>> Partition<T>(this IEnumerable<T> source, int partitionSize) { if (partitionSize <= 0) { throw new ArgumentOutOfRangeException(nameof(partitionSize)); } int innerListCounter = 0; int numberOfPackets = 0; foreach (var item in source) { innerListCounter++; if (innerListCounter == partitionSize) { yield return source.Skip(numberOfPackets * partitionSize).Take(partitionSize); innerListCounter = 0; numberOfPackets++; } } if (innerListCounter > 0) { yield return source.Skip(numberOfPackets * partitionSize); } } /// <summary> /// 将 source 中的条目按照 numberOfChunks 参数指定的分组数进行切分 /// http://stackoverflow.com/questions/438188/split-a-collection-into-n-parts-with-linq/13744322#13744322 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="source"></param> /// <param name="numberOfChunks"></param> /// <returns></returns> public static IEnumerable<IEnumerable<T>> Split<T>(this ICollection<T> source, int numberOfChunks) { if (numberOfChunks <= 0 || numberOfChunks > source.Count) { throw new ArgumentOutOfRangeException(nameof(numberOfChunks)); } int sizePerPacket = source.Count / numberOfChunks; int extra = source.Count % numberOfChunks; for (int i = 0; i < numberOfChunks - extra; i++) { yield return source.Skip(i * sizePerPacket).Take(sizePerPacket); } int alreadyReturnedCount = (numberOfChunks - extra) * sizePerPacket; int toReturnCount = extra == 0 ? 0 : (source.Count - numberOfChunks) / extra + 1; for (int i = 0; i < extra; i++) { yield return source.Skip(alreadyReturnedCount + i * toReturnCount).Take(toReturnCount); } } }
两个方法以不同的形式对 IEnumerable 集合中的元素进行分组,非常有用,而且没有容器操作等动态内存分配,不可能再快了。
相关文章推荐
- 本周ASP.NET英文技术文章推荐[09/23 - 09/29]:IIS 7.0、Facebook.NET、ASP.NET AJAX、ModalPopupExtender、扩展方法、LinqDataSource、ListView、Visual Studio
- 综合应用WPF/WCF/WF/LINQ之二十:ListView控件中几个常用的扩展方法
- 关于 Linq 中的 Aggregate 扩展方法的实例
- 本周ASP.NET英文技术文章推荐[09/23 - 09/29]:IIS 7.0、Facebook.NET、ASP.NET AJAX、ModalPopupExtender、扩展方法、LinqDataS
- Linq排序、分组、模糊查询、调用外部方法、直接执行SQL语句、事务、修改数据
- [C#3.0体验]Orcas中内置的LinQ,XLinQ[DLinQ]扩展方法
- 委托是什么?匿名方法是什么?在C# 3.0中,Lambda表达式是什么?扩展方法是什么?LINQ是什么?您觉得C# 3.0中还有哪些重要的特性,它们带来了什么优势?BCL中哪些类库和这些特性有关?您平时最常用哪些
- 使用Enumerable.OfType<T>扩展方法实现非泛型集合的Linq查询
- LINQ用于数据库访问的基本方法示例
- 从扩展方法到匿名方法再到LINQ
- Linq的那些事——从Linq扩展方法回顾C#语言基础
- 为LINQ服务的C#新特性总结篇---扩展方法,匿名委托,lambda表达式,Action委托,Func委托,Linq中的order by,top和sum函数
- linq to sql 扩展方法
- Linq原理(扩展方法)
- System.Linq.Enumerable类中的两个where方法都是对于IEnumerable的扩展方法,那LINQ是如何支持Array的
- 【收藏】本周ASP.NET英文技术文章推荐[09/23 - 09/29]:IIS 7.0、Facebook.NET、ASP.NET AJAX、ModalPopupExtender、扩展方法、LinqDataSource、ListView、Visual Studio
- LINQ学习笔记之二:扩展方法与隐藏类型
- C#4.0新特性之(四)新的LINQ扩展方法-Zip()
- 学习Linq之扩展方法
- LINQ学习(扩展方法,委托,Lambda表达式) 第二篇