在 C# 中使用拆分分区列表

Consume Split Partition List in C#

如何使用这种拆分列表的方法<>

private List<List<T>> SplitPartition<T>(this IEnumerable<T> collection, int size)
{
    var chunks = new List<List<T>>();
    var count = 0;
    var temp = new List<T>();

    foreach (var element in collection)
    {
        if (count++ == size)
        {
            chunks.Add(temp);
            temp = new List<T>();
            count = 1;
        }
        temp.Add(element);
    }
    chunks.Add(temp);

    return chunks;
}

我想在我现有的代码中实现这个列表分区:

public void ExportToCsv()
{
    List<GenerateModel> members = getDataTop5000(); // I got data from my List of Data with return List<>

    int offset = 0;
    const int numberPerBatch = 500000; // count parameter.
    double LoopMax = Math.Ceiling(members.Count / (double)numberPerBatch);

    var PartitionMembers = members.SplitPartition(numberPerBatch); //error here

    while (offset < LoopMax)
    {
        //do the index of partion here  PartitionMembers

        offset++;
    }
}

任何建议或示例如何使用这些方法?这真的是我需要的分区到我的列表。当我尝试使用该方法时,出现如下错误:

List' does not contain a definition for 'SplitPartition' and no accessible extension method 'SplitPartition' accepting a first argument of type 'List' could be found (are you missing a using directive or an assembly reference?)

看不到您的完整代码,但是:

  • 扩展方法需要属于 static class 和
  • 此 class 和方法需要在调用代码中可见。

特别是,我可以看到你的 ExportToCsv 不是静态的,所以它不属于静态 class,所以我可以推断出你的 private 扩展方法或者:

  • 不属于静态 class,或
  • 与您的 ExportToCsv 方法属于不同的 class,因此无法从中看到

所以做一个public staticclass来保存扩展方法,标记方法本身public static,你应该在业务中。

更多详情:https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/how-to-implement-and-call-a-custom-extension-method

我认为您最好为此推出自己的解决方案。假设您已经下载了 5000 个成员并想将它们写入 50 个成员块(100 个文件)的文件中,您可以简单地执行以下操作:

StringBuilder sb = new StringBuilder(10000);
int x= 0;
foreach(var m in members){
  if(++x%50 == 0){
    File.WriteAllText(sb.ToString(), $@"c:\temp\{x%50}.csv");
    sb.Length = 0;
  }
  sb.AppendLine(m.ToCsvRepresentationEtc());
}

我要表达的意思不是关于写入文件,而是关于知道你想用你的块做什么(例如写入文件)并进行一次可枚举并切割成正在完成的块通过改变你不时采取的行动。在此示例中,更改操作是一个简单的模数,它清空 StringBuilder 的缓冲区并根据模数写入文件名。这比在预分块时消耗大量内存更可取(根据所涉及的数字,拆分例程的性能可能会很糟糕;它不会尝试根据数字提供任何适当大小的列表)

至少考虑重写分块,使其使用直接的 2d(锯齿状)数组或预先提供容量的列表;你知道它们需要多大,从传入的列表有多大和块大小:


public static class ListExtensions{

  public List<List<T>> SplitPartition<T>(this IEnumerable<T> collection, int size)
  {
    var chunks = new List<List<T>>(collection.Count/size + 1);
    var temp = new List<T>(size);

    foreach (var element in collection)
    {
        if (temp.Count == size)
        {
            chunks.Add(temp);
            temp = new List<T>(size);
        }
        temp.Add(element);
    }
    chunks.Add(temp);

    return chunks;
  }
}