Linq:如何按最大数量分组

12

上下文

  • 我有一列项目(长度任意),我想要按照固定大小分组
  • 例如:我有12个顾客 [0,1,2,3,4,5,6,7,8,9,10,11],想要将它们分为固定大小的块,比如每块5个,于是结果是 [0,1,2,3,4] [5,6,7,8,9] [10,11]
  • 注意:事实上我不会处理客户或单调递增的整数。我只是举例简化问题。

我的问题

我该如何用LINQ查询语法写出简单明了的代码来完成这种分组?

背景

  • 我已经知道怎样使用LINQ的语法来按值进行分组,例如(通过客户ID来对销售额进行分组),但我不知道如何使用LINQ来清晰、简洁地表达“chunking”。我不确定是否有一种简单明了的方法来实现这种分组。
  • 我已经用C#普通代码实现了解决方案,因此我并没有在这个问题上被阻塞,而是寻求一种用LINQ表达它的方式(同样也要清晰简洁)。

4个回答

11
你可以按照(index/chunkSize)进行分组。例如:
    var result =
        from i in array.Select((value, index) => new { Value = value, Index = index })
        group i.Value by i.Index / chunkSize into g
        select g;

2
这是那些罕见的情况之一,普通的for循环和字典比LINQ更短且更易理解... - Ray

4

对于那些喜欢使用带有lambda表达式的LINQ方法的人,这里是Dimitriy Matveev的答案转换后的结果:

var result = array
    .Select((value, index) => new { Value = value, Index = index })
    .GroupBy(i => i.Index / chunkSize, v => v.Value);

如果你只需要一个 value 数组,而不是一个 IGrouping<T1, T2>,那么请添加以下内容:
.Select(x => x.ToArray())

1

扩展方法(使用杰西的答案):

public static IEnumerable<T[]> GroupToChunks<T>(this IEnumerable<T> items, int chunkSize)
{
    if (chunkSize <= 0)
    {
        throw new ArgumentException("Chunk size must be positive.", "chunkSize");
    }

    return
        items.Select((item, index) => new { item, index })
             .GroupBy(pair => pair.index / chunkSize, pair => pair.item)
             .Select(grp => grp.ToArray());
}

0

要进行实际的分组,难道不应该是:

var result = array
.Select((value, index) => new { Value = value, Index = index})
.GroupBy(i => i.Index / chunk, v => v.Value);

Steven - 你说得对。我已经更新了我的回答。感谢你指出这个问题。此外,请注意StackOverflow(以及整个StackExchange)并不是论坛风格,您应该回答问题,而不是回复“上面”的回复。我知道你可能没有足够的声望添加评论。所以,无论如何,只是想帮忙解决。 - Jesse

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接