2

我正在处理尝试在 C# 2.0 中实现 IEnumerable(和 ICollection)的自定义集合类中的项目块。例如,假设我一次只想要 1000 件物品,而我的收藏中有 3005 件物品。我有一个可行的解决方案,我在下面演示,但它看起来很原始,我认为必须有更好的方法来做到这一点。

这是我所拥有的(例如,我使用 C# 3.0 的 Enumerable 和 var,只需将这些引用替换为您心中的自定义类):

var items = Enumerable.Range(0, 3005).ToList();
int count = items.Count();
int currentCount = 0, limit = 0, iteration = 1;

List<int> temp = new List<int>();

while (currentCount < count)
{
    limit = count - currentCount;

    if (limit > 1000)
    {
        limit = 1000 * iteration;
    }
    else
    {
        limit += 1000 * (iteration - 1);
    }
    for (int i = currentCount; i < limit; i++)
    {
        temp.Add(items[i]);
    }

    //do something with temp

    currentCount += temp.Count;
    iteration++;
    temp.Clear();
}

任何人都可以在 C# 2.0 中提出一种更优雅的方法吗?我知道这个项目是否来自过去 5 年,我可以使用 Linq(如这里这里所示)。我知道我的方法会起作用,但我不想让我的名字与如此丑陋的(在我看来)代码相关联。

谢谢。

4

2 回答 2

8

首先 。yield是你的朋友,它是在 2.0 中引入的。考虑:

public static IEnumerable<List<T>> Chunk<T>(IEnumerable<T> source, int chunkSize)
{
  List<T> list = new List<T>(chunkSize);
  foreach(T item in source)
  {
    list.Add(item);
    if(list.Count == chunkSize)
    {
      yield return list;
      list = new List<T>(chunkSize);
    }
  }
  //don't forget the last one!
  if(list.Count != 0)
    yield return list;
}

然后我们在类型和大小上是灵活的,所以它可以很好地重复使用。唯一限制为 2.0 意味着我们不能将其作为扩展方法。

于 2012-08-29T21:12:12.670 回答
2

有几种方法可以解决这个问题。

如果您只想将每个项目与其所属的块的索引相关联:

int processed = 0;
foreach (int item in items)
{
    int chunkIndex = processed++ / CHUNK_SIZE;
    ProcessItem(item, chunkIndex);
}

如果您想批量处理项目,但不需要一次收集整个块:

int processed = 0, count = items.Count;
List<int> chunk = new List<int>(CHUNK_SIZE);
foreach (int item in items)
{
    chunk.Add(item);
    if (++processed % CHUNK_SIZE == 0 || processed == count) {
        ProcessChunk(chunk);
        chunk.Clear();
    }
}

如果要将所有块作为列表列表:

int processed = 0, count = items.Count;
List<List<int>> chunks = new List<List<int>>();
foreach (int item in items)
{
    int chunkIndex = processed++ / CHUNK_SIZE;
    if (chunks.Count == chunkIndex) {
        chunks.Add(new List<int>(CHUNK_SIZE));
    }

    chunks[chunkIndex].Add(item);
}
于 2012-08-29T21:07:28.230 回答