• Stackoverflow 珠玑:用于分组的 LINQ 扩展方法


    从 stackoverflow.com 上抄来的,将 IEnumerable 中的元素进行切分的方法,无动态内存分配,地球上最快的实现:

     1 public static class LinqExtensions
     2     {
     3         /// <summary>
     4         /// 将 source 中的条目按照 partitionSize 指定的每组数量进行分组
     5         /// http://stackoverflow.com/questions/3773403/linq-partition-list-into-lists-of-8-members
     6         /// </summary>
     7         /// <typeparam name="T"></typeparam>
     8         /// <param name="source"></param>
     9         /// <param name="partitionSize"></param>
    10         /// <returns></returns>
    11         public static IEnumerable<IEnumerable<T>> Partition<T>(this IEnumerable<T> source, int partitionSize)
    12         {
    13             if (partitionSize <= 0)
    14             {
    15                 throw new ArgumentOutOfRangeException(nameof(partitionSize));
    16             }
    17 
    18             int innerListCounter = 0;
    19             int numberOfPackets = 0;
    20             foreach (var item in source)
    21             {
    22                 innerListCounter++;
    23                 if (innerListCounter == partitionSize)
    24                 {
    25                     yield return source.Skip(numberOfPackets * partitionSize).Take(partitionSize);
    26                     innerListCounter = 0;
    27                     numberOfPackets++;
    28                 }
    29             }
    30 
    31             if (innerListCounter > 0)
    32             {
    33                 yield return source.Skip(numberOfPackets * partitionSize);
    34             }
    35         }
    36 
    37 
    38         /// <summary>
    39         /// 将 source 中的条目按照 numberOfChunks 参数指定的分组数进行切分
    40         /// http://stackoverflow.com/questions/438188/split-a-collection-into-n-parts-with-linq/13744322#13744322
    41         /// </summary>
    42         /// <typeparam name="T"></typeparam>
    43         /// <param name="source"></param>
    44         /// <param name="numberOfChunks"></param>
    45         /// <returns></returns>
    46         public static IEnumerable<IEnumerable<T>> Split<T>(this ICollection<T> source, int numberOfChunks)
    47         {
    48             if (numberOfChunks <= 0 || numberOfChunks > source.Count)
    49             {
    50                 throw new ArgumentOutOfRangeException(nameof(numberOfChunks));
    51             }
    52 
    53             int sizePerPacket = source.Count / numberOfChunks;
    54             int extra = source.Count % numberOfChunks;
    55 
    56             for (int i = 0; i < numberOfChunks - extra; i++)
    57             {
    58                 yield return source.Skip(i * sizePerPacket).Take(sizePerPacket);
    59             }
    60 
    61             int alreadyReturnedCount = (numberOfChunks - extra) * sizePerPacket;
    62             int toReturnCount = extra == 0 ? 0 : (source.Count - numberOfChunks) / extra + 1;
    63             for (int i = 0; i < extra; i++)
    64             {
    65                 yield return source.Skip(alreadyReturnedCount + i * toReturnCount).Take(toReturnCount);
    66             }
    67         }
    68 
    69 
    70     }

    两个方法以不同的形式对 IEnumerable 集合中的元素进行分组,非常有用,而且没有容器操作等动态内存分配,不可能再快了。

  • 相关阅读:
    【2020】iOS证书(.p12)和描述文件(.mobileprovision)一键申请流程
    苹果开发者账号正在调查原因解答
    【2020最新】苹果iOS开发者到期续费流程
    【2020】联系苹果客服电话入口及步骤
    苹果电脑Transporter App及Windows上传ipa工具Appuploader
    一文学会苹果TestFlight上架详细流程
    iOS APP打包上线App Store七个步骤详解(2020版)
    技术分享 | mysql 表数据校验
    MySQL 自带的4个系统数据库的说明
    linux定时任务crontab怎样执行root命令
  • 原文地址:https://www.cnblogs.com/oldrev/p/6660483.html
Copyright © 2020-2023  润新知