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

时间:2010-08-18 17:17:43

标签: c# linq arrays .net-4.0

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

E.g

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可能是一种简单的方法吗?

5 个答案:

答案 0 :(得分:25)

这将生成一个包含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();

答案 1 :(得分:9)

我认为没有一个很好的内置方法,但你可以写一个像下面这样的方法。

public static IEnumerable<IEnumerable<T>> GroupInto<T>(
  this IEnumerable<T> source,
  int count) {

  using ( var e = source.GetEnumerator() ) {
    while ( e.MoveNext() ) { 
      yield return GroupIntoHelper(e, count);
    }
  }    
}

private static IEnumerable<T> GroupIntoHelper<T>(
  IEnumerator<T> e,
  int count) {

  do {
    yield return e.Current;
    count--;
  } while ( count > 0 && e.MoveNext());
}

答案 2 :(得分:5)

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<IEnumerable<T>>而不是T[][],那么您可以完全忽略ToArray次来电:

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

答案 3 :(得分:2)

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

    private static T[][] SliceArray<T>(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;
    }

答案 4 :(得分:1)

MoreLinq提供Batch扩展方法