Каков наилучший способ сгруппировать массив в список массива из n элементов, каждый из которых находится в c # 4.
Например,
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<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());
}
Если вы работаете именно с массивами, а не с общими 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;
}
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);