c# - 如何批量循环遍历IEnumerable

标签 c# ienumerable

<分区>

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

我如何从 IEnumerable 开始一次提取 1000 个 ID,做一些其他事情,然后获取下一批 1000 等等?

这可能吗?

最佳答案

您可以使用 MoreLINQ's Batch operator (可从 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)
    {
        Array.Resize(ref bucket, count);
        yield return bucket.Select(x => x);
    }
}

顺便说一句,为了提高性能,您可以简单地返回存储桶而无需调用 Select(x => x)。 Select 针对数组进行了优化,但仍然会在每个项目上调用选择器委托(delegate)。所以,在你的情况下,最好使用

yield return bucket;

关于c# - 如何批量循环遍历IEnumerable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15414347/

相关文章:

c# - 为适当的构造函数注入(inject)和 ISP(SOLID)定义抽象

c# - 更改 DataTable 列中每个单元格的值

c# - List 和 IEnumerable 之间的实际区别

c# - 我应该始终返回 IEnumerable<T> 而不是 IList<T> 吗?

C#:要实现 XML 序列化,从 IEnumerable 继承的类型必须具有 Add(System.Object) 的实现

c# - 如何模拟扩展 IEnumerable 的接口(interface)

c# - 如果 catch block 包含 continue 语句,finally block 何时执行?

c# - 使用 Razor 将 HtmlHelper 实例传递给另一个方法 MVC3

c# - LINQ:如何强制使用基于值的引用?

c# - Scala 中 IEnumerable LINQ 等价物的图表?