使用LINQ将列表转换为列表列表

我有一个值列表:

IList values = { V1, V2, V3, V4, V5, V6, V7 }; 

我想将列表转换为列表列表,其中每个子列表都是指定的大小。 每个子列表的大小可能会有所不同。 例如:

 IList<IList> values_size2 = { { V1, V2 }, { V3, V4 }, { V5, V6 }, { V7 } }; IList<IList> values_size3 = { { V1, V2, V3 }, { V4, V5, V6 }, { V7 } }; IList<IList> values_size4 = { { V1, V2, V3, V4 }, { V5, V6, V7 } }; 

我可以使用嵌套循环很容易地做到这一点,但是想知道是否有一种聪明的方法来使用LINQ做到这一点?

我最初的想法是以某种方式使用Aggregate方法,但没有任何想法立即浮现在脑海中。

谢谢。

这是一个基于IEnumerable的通用Batch函数。 您可以将IEnumerable>的返回类型更改为IEnumerable>而不进行其他更改(因为在我的实现中它已经是一个列表。要更改整个内容以返回列表列表” d需要在结果上调用`ToList,或者做一个更复杂的重构。

请注意,从技术上讲,这不是使用LINQ,它只是创建一个使用LINQ常用的相同样式和模式的新方法。

 public static IEnumerable> Batch(this IEnumerable source , int batchSize) { //TODO validate parameters List buffer = new List(); foreach (T item in source) { buffer.Add(item); if (buffer.Count >= batchSize) { yield return buffer; buffer = new List(); } } if (buffer.Count >= 0) { yield return buffer; } } 

您可以使用MoreLINQ Batch扩展(可从Nuget获得 ):

 IList> values_size2 = values.Batch(2); IList> values_size3 = values.Batch(3); IList> values_size4 = values.Batch(4); 

您也可以在这里查看来源。

鉴于其他人的答案,我使用纯LINQ提出了我自己的解决方案,如下所示:

 IList> Batch(IList values, int batchSize) { return values.Aggregate( new List>(), (state, next) => { IList batch = (state.Count > 0) ? state[state.Count - 1] : null; if ((batch == null) || (batch.Count == batchSize)) { batch = new List(batchSize); state.Add(batch); } batch.Add(next); return state; }); } 

这可能不如使用IEnumerable有效,但在我的情况下我处理的是小集,所以它应该没关系。

我将选择Servy的答案作为“正确的”答案,因为它不依赖于外部库并引导我使用我的解决方案。

谢谢大家的帮助:)

  public static IEnumerable> Chunks(this IEnumerable source, int chunkSize) { while (source.Any()) { yield return source.Take(chunkSize); source = source.Skip(chunkSize); } }