【问题标题】:How do I split a list based on index in C#?如何在 C# 中根据索引拆分列表?
【发布时间】:2011-08-01 07:36:24
【问题描述】:

我现在有一个包含大约 190 个元素的列表。如何将列表拆分为较小的列表,每个列表中最多包含 50 个元素?

结果可能是包含 50、50、50 和 40 个元素的列表。

【问题讨论】:

标签: c# list split


【解决方案1】:

假设您的意思是List<T>,您可以重复使用GetRange 方法。哎呀,你可以用 LINQ 做到这一点:

var lists = Enumerable.Range(0, (list.Count + size - 1) / size)
      .Select(index => list.GetRange(index * size,
                                     Math.Min(size, list.Count - index * size)))
      .ToList();

当然,您也可以只使用循环:

public static List<List<T>> Split(List<T> source, int size)
{
    // TODO: Validate that size is >= 1
    // TODO: Prepopulate with the right capacity
    List<List<T>> ret = new List<List<T>>();
    for (int i = 0; i < source.Count; i += size)
    {
        ret.Add(source.GetRange(i, Math.Min(size, source.Count - i)));
    }
    return ret;
}

这比使用GroupBy 更有效,尽管它仅限于List&lt;T&gt; 作为输入。

我们有另一个使用 IEnumerable&lt;T&gt; in MoreLINQ in Batch.cs 的实现。

【讨论】:

  • 历史:我从来没有在 -1 上看到过 Jon,甚至连一瞬间都没有。我会代替他问:减号选民是否愿意详细说明? --> 当然他打败了我 :-)
  • @Jon,我没有投反对票,但我认为这是由于较晚的示例。
  • -1 表示“即将推出”的一半答案没有意义。
  • @Sanjeevakumar: GetRange 确实是它的核心……其余的都很简单,这显示了从另一个列表创建一个列表的有效方法。我想在创建示例代码时提供 那个 信息。当然,我现在已经用两个示例扩展了答案,以及指向另一个实现的链接,它仍然比使用 GroupBy 更有效......
  • 你为什么要发表一篇关于“样品来了”的文章?这样做有什么好处?
【解决方案2】:

你可以使用 LINQ:

var list = Enumerable.Range(1, 190);
var sublists = list
    .Select((x, i) => new { Index = i, Value = x })
    .GroupBy(x => x.Index / 50)
    .Select(x => x.Select(v => v.Value).ToList())
    .ToArray();

【讨论】:

  • 感谢您的建议,但 Jon 的 foreach 更简洁。
【解决方案3】:

我尝试了一种递归方法。只是看看它会是什么样子。

List<List<T>> SplitIntoChunks<T>(IEnumerable<T> originalList, int chunkSize)
{
    if(originalList.Take(1).Count() == 0)
    {
        return new List<List<T>>();
    }

    var chunks = new List<List<T>> {originalList.Take(chunkSize).ToList()};
    chunks.AddRange(SplitIntoChunks(originalList.Skip(chunkSize), chunkSize));
    return chunks;
}

【讨论】:

    【解决方案4】:
    var list = new List<int>(Enumerable.Range(1,190));
    var page_size = 50;
    var max_pages = 1 + list.Count() / page_size;
    
    for(int page = 1; page <= max_pages; page++) {
      var chunk = list.Skip(page_size * (page-1)).Take(page_size);
      // do whatever
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-05
      • 2020-05-02
      • 2022-12-14
      • 2020-01-14
      • 1970-01-01
      • 2016-09-01
      相关资源
      最近更新 更多