C# linq 如何分批循环遍历IEnumerable?/C#/.NET6新特性之Enumerable.Chunk

我正在开发具有“IEnumerable用户”的c#程序,其中存储了400万用户的ID。我需要遍历Ienummerable并每次提取一批1000个ID,以另一种方法执行一些操作。

我如何从Ienumerable的开始一次提取1000个ID ...做一些其他事情然后获取下一批1000个

 

可以使用linq morelinq库的 batch方法(可从NuGet获得):

foreach(IEnumerable<User> batch in users.Batch(1000))
   // use batch

如果简单使用库不是一种选择,则可以重新使用实现:

public static IEnumerable<IEnumerable<T>> Batch<T>(
        this IEnumerable<T> source, int size)
{
    T[] bucket = null;
    var count = 0;

    foreach (var item in source)
    {
       if (bucket == null)
           bucket = new T[size];

       bucket[count++] = item;

       if (count != size)                
          continue;

       yield return bucket.Select(x => x);

       bucket = null;
       count = 0;
    }

    // Return the last bucket with all remaining elements
    if (bucket != null && count > 0)            
        yield return bucket.Take(count);            
}

C#/.NET6新特性之Enumerable.Chunk

Enumerable.Chunk<TSource>(IEnumerable<TSource>, Int32) 方法 (System.Linq) | Microsoft Learn 

https://learn.microsoft.com/ZH-CN/dotnet/api/system.linq.enumerable.chunk?view=net-7.0

.net6新增了一个语法糖 对于分块读取,断点续传,大文件分段读取,我们可以直接用一句话就可以代替繁琐的操作
比如我们有1005页书 要按每10页分一组 我们可以进行一下操作

static void Main(string[] args)
{
//新特性一句话搞定
List<int[]> list = Enumerable.Range(1, 1005).Chunk(10).ToList();

//以前的方法
List<int> list1 = Enumerable.Range(1, 1005).ToList();

var totalCount = list1.Count;

var pageSize = 100;

var pageCount = Convert.ToInt32(totalCount / (double)pageSize);

List<int[]> list2 = new List<int[]>();

for (int i = 0; i < pageCount; i++)
{
int[] chunk = list1.Skip(i * pageSize).Take(pageSize).ToArray();

list2.Add(chunk);
}
//以前这么长
}

 

 
posted @ 2020-10-25 19:34  跟着阿笨一起玩.NET  阅读(1442)  评论(0编辑  收藏  举报