如何将数组分成一组n个元素?

在c#4中将数组分组为n个元素数组的列表的最佳方法是什么?

例如

string[] testArray = { "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8" }; 

如果我们采取n = 3,应该分成。

 string[] A1 = {"s1", "s2", "s3"}; string[] A2 = {"s4", "s5", "s6"}; string[] A3 = {"s7", "s8"}; 

使用LINQ可能是一种简单的方法吗?

这将生成一个包含3个元素的字符串数组:

 int i = 0; var query = from s in testArray let num = i++ group s by num / 3 into g select g.ToArray(); var results = query.ToArray(); 

我不认为有一个很好的内置方法,但你可以编写如下的方法。

 public static IEnumerable> GroupInto( this IEnumerable source, int count) { using ( var e = source.GetEnumerator() ) { while ( e.MoveNext() ) { yield return GroupIntoHelper(e, count); } } } private static IEnumerable GroupIntoHelper( IEnumerator e, int count) { do { yield return e.Current; count--; } while ( count > 0 && e.MoveNext()); } 
 int size = 3; var results = testArray.Select((x, i) => new { Key = i / size, Value = x }) .GroupBy(x => x.Key, x => x.Value, (k, g) => g.ToArray()) .ToArray(); 

如果您不介意将结果输入为IEnumerable>而不是T[][]那么您可以完全省略ToArray调用:

 int size = 3; var results = testArray.Select((x, i) => new { Key = i / size, Value = x }) .GroupBy(x => x.Key, x => x.Value); 

如果它实际上是你正在使用的数组而不是一般的IEnumerables,特别是如果数组非常大,那么这种方法是一种非常快速且具有内存效率的方法。 如果你真的只想要一个LINQ语句,那就再也不要了。

  private static T[][] SliceArray(T[] source, int maxResultElements) { int numberOfArrays = source.Length / maxResultElements; if (maxResultElements * numberOfArrays < source.Length) numberOfArrays++; T[][] target = new T[numberOfArrays][]; for (int index = 0; index < numberOfArrays; index++) { int elementsInThisArray = Math.Min(maxResultElements, source.Length - index * maxResultElements); target[index] = new T[elementsInThisArray]; Array.Copy(source, index * maxResultElements, target[index], 0, elementsInThisArray); } return target; } 

您可以使用此扩展程序

 public static class Extension { private static IEnumerable Split(this TList value, int countOfEachPart) where TList : IEnumerable { int cnt = value.Count() / countOfEachPart; List> result = new List>(); for (int i = 0; i <= cnt; i++) { IEnumerable newPart = value.Skip(i * countOfEachPart).Take(countOfEachPart).ToArray(); if (newPart.Any()) result.Add(newPart); else break; } return result.Cast(); } public static IEnumerable> Split(this IDictionary value, int countOfEachPart) { IEnumerable> result = value.ToArray() .Split(countOfEachPart) .Select(p => p.ToDictionary(k => k.Key, v => v.Value)); return result; } public static IEnumerable> Split(this IList value, int countOfEachPart) { return value.Split, T>(countOfEachPart); } public static IEnumerable Split(this T[] value, int countOfEachPart) { return value.Split(countOfEachPart); } public static IEnumerable> Split(this IEnumerable value, int countOfEachPart) { return value.Split, T>(countOfEachPart); } } 

MoreLinq提供Batch扩展方法