Разделение массива с помощью LINQ
у меня есть коллекция одномерных, как это:
[1,2,4,5.....n]
Я хотел бы преобразовать эту коллекцию в двумерную коллекцию, как это:
[[1,2,3],
[4,5,6],
...]
в основном я хочу сгруппировать или разделить, если хотите, массив в группах из " n " членов
Я могу сделать это с foreach
оператор, но в настоящее время я изучаю LINQ, поэтому вместо итерации по всем элементам и создания нового массива вручную я хотел бы использовать функции LINQ (если применимо)
есть ли функция LINQ, которая поможет мне в этом??
Я думал в GroupBy
или SelectMany
Я не знаю, помогут ли они мне, но они могут
любая помощь будет по-настоящему оценена=):**
6 ответов
вы можете группировать по индексу, разделенному на размер пакета, например:
var batchSize = 3;
var batched = orig
.Select((Value, Index) => new {Value, Index})
.GroupBy(p => p.Index/batchSize)
.Select(g => g.Select(p => p.Value).ToList());
использовать MoreLinq.Партия
var result = inputArray.Batch(n); // n -> batch size
пример
var inputs = Enumerable.Range(1,10);
var output = inputs.Batch(3);
var outputAsArray = inputs.Batch(3).Select(x=>x.ToArray()).ToArray(); //If require as array
вы хотите Take()
и Skip()
. Эти методы позволят вам разделить IEnumerable
. Тогда вы можете использовать Concat()
чтобы снова хлопнуть их вместе.
приведенный ниже пример разделит массив на группы по 4 элемента каждый.
int[] items = Enumerable.Range(1, 20).ToArray(); // Generate a test array to split
int[][] groupedItems = items
.Select((item, index) => index % 4 == 0 ? items.Skip(index).Take(4).ToArray() : null)
.Where(group => group != null)
.ToArray();
это не чистый LINQ, но он предназначен для использования с ним:
public static class MyEnumerableExtensions
{
public static IEnumerable<T[]> Split<T>(this IEnumerable<T> source, int size)
{
if (source == null)
{
throw new ArgumentNullException("source can't be null.");
}
if (size == 0)
{
throw new ArgumentOutOfRangeException("Chunk size can't be 0.");
}
List<T> result = new List<T>(size);
foreach (T x in source)
{
result.Add(x);
if (result.Count == size)
{
yield return result.ToArray();
result = new List<T>(size);
}
}
}
}
его можно использовать из вашего кода как:
private void Test()
{
// Here's your original sequence
IEnumerable<int> seq = new[] { 1, 2, 3, 4, 5, 6 };
// Here's the result of splitting into chunks of some length
// (here's the chunks length equals 3).
// You can manipulate with this sequence further,
// like filtering or joining e.t.c.
var splitted = seq.Split(3);
}
все просто:
static class LinqExtensions
{
public static IEnumerable<IEnumerable<T>> ToPages<T>(this IEnumerable<T> elements, int pageSize)
{
if (elements == null)
throw new ArgumentNullException("elements");
if (pageSize <= 0)
throw new ArgumentOutOfRangeException("pageSize","Must be greater than 0!");
int i = 0;
var paged = elements.GroupBy(p => i++ / pageSize);
return paged;
}
}