简体   繁体   English

如何在foreach循环中对迭代的元素进行分段

[英]How do I segment the elements iterated over in a foreach loop

I need to loop through an entire list of users, but need to grab 20 at a time. 我需要循环遍历整个用户列表,但需要一次抓取20个。

foreach (var student in Class.Students.Take(20))
{
   Console.WriteLine("You belong to Group " + groupNumber);
   groupNumber++;
}

This way the first 20 will belong to Group 1, the second 20 to Group 2, and so on. 这样,前20个将属于组1,第二个20属于组2,依此类推。

Is Take the correct syntax for this? 采取正确的语法吗? I believe Take will take 20 then be done. 我相信Take将花费20来完成。 Thanks! 谢谢!

You can do something like this: 你可以这样做:

int i = 0;
foreach (var grouping in Class.Students.GroupBy(s => ++i / 20))
    Console.WriteLine("You belong to Group " + grouping.Key.ToString());

For a similar problem I once made an extension method: 对于类似的问题,我曾经做过一个扩展方法:

public static IEnumerable<IEnumerable<T>> ToChunks<T>(this IEnumerable<T> enumerable, int chunkSize)
{
    int itemsReturned = 0;
    var list = enumerable.ToList(); // Prevent multiple execution of IEnumerable.
    int count = list.Count;
    while (itemsReturned < count)
    {
        int currentChunkSize = Math.Min(chunkSize, count - itemsReturned);
        yield return list.GetRange(itemsReturned, currentChunkSize);
        itemsReturned += currentChunkSize;
    }
}

Note that the last chunk may be smaller than the specified chunk size. 请注意,最后一个块可能小于指定的块大小。

EDIT The first version used Skip()/Take() , but as Chris pointed out, GetRange is considerably faster. 编辑第一个版本使用Skip()/Take() ,但正如克里斯指出的那样, GetRange要快得多。

You could project the group number onto each item in the original list using Select and an anonymous type like this: 您可以使用Select和匿名类型将组编号投影到原始列表中的每个项目上,如下所示:

var assigned = Class.Students.Select(
  (item, index) => new 
  { 
    Student = item, 
    GroupNumber = index / 20 + 1 
  });

Then you can use it like this: 然后你可以像这样使用它:

foreach (var item in assigned)
{
  Console.WriteLine("Student = " + item.Student.Name);
  Console.WriteLine("You belong to Group " + item.GroupNumber.ToString());
}

Or if you wanted to pick off a particular group. 或者,如果你想挑选一个特定的群体。

foreach (var student in assigned.Where(x => x.GroupNumber == 5))
{
  Console.WriteLine("Name = " + student.Name);
}

Or if you wanted to actually group them to perform aggregates 或者,如果您想实际将它们分组以执行聚合

foreach (var group in assigned.GroupBy(x => x.GroupNumber))
{
  Console.WriteLine("Average age = " + group.Select(x => x.Student.Age).Average().ToString());
}

Now if you just want to lump the items in batches and you do not care about having the batch number information you can create this simple extension method. 现在,如果您只想批量生产物品并且不关心批次编号信息,则可以创建这种简单的扩展方法。

public static IEnumerable<IEnumerable<T>> Batch<T>(this IEnumerable<T> target, int size)
{
  var assigned = target.Select(
      (item, index) => new
      {
          Value = item,
          BatchNumber = index / size
      });
  foreach (var group in assigned.GroupBy(x => x.BatchNumber))
  {
      yield return group.Select(x => x.Value);
  }
}

And you could use your new extension method like this. 你可以像这样使用你的新扩展方法。

foreach (var batch in Class.Students.Batch(20))
{
  foreach (var student in batch)
  {
    Console.WriteLine("Student = " + student.Name);
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何限制在foreach循环中迭代的元素数量? - How do I limit the number of elements iterated over in a foreach loop? 为什么我不能用 linq 迭代可以用 foreach 迭代的东西? - Why can I not iterate over something with linq that can be iterated over with foreach? 如何跳过“foreach”循环的迭代? - How do I skip an iteration of a `foreach` loop? 我如何通过使用foreach循环一列和另一个foreach填充第二列来填充C#列表视图,以便第二个循环不会首先覆盖 - How can i fill a C# listview by using foreach loop a column and another foreach for second column so that 2nd loop do not over write first 如何编写 foreach 循环来对 Lamba 表达式中的元素求和? - How can I write foreach loop to sum elements in lamba expression? 如何在for循环或foreach循环中比较2个arraylist - How do I compare 2 arraylist in a for loop or foreach loop C#如何将此foreach循环转换为for循环 - C# How do I translate this foreach loop to a for loop 如何将 foreach 循环更改为 for 循环? - How do I change my foreach loop to a for loop? 如何跳过已经迭代的行,但读取未迭代的下一行? - How do I SKIP the already iterated rows but read the next rows that are not being iterated? 如何在 C# 中使用 foreach 遍历 JsonObject - How do I iterate over a JsonObject with foreach in C#
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM