Linq: как группировать по максимальному количеству элементов
контекст
- у меня есть список элементов (или произвольной длины). Я хотел бы сгруппировать их в "куски" определенного размера
- пример: у меня есть 12 клиентов [0,1,2,3,4,5,6,7,8,9,10,11] и я хочу сгруппировать куски 5, которые дадут [0,1,2,3,4] [5,6,7,8,9] [10,11]
- Примечание: На самом деле я не работаю с клиентами или возрастающую последовательность целых чисел. Я выбрал это, чтобы упростить вопрос
мой Вопрос
как я могу сформулировать простой запрос LINQ (используя синтаксис запроса), который выполняет эту группировку?
фон
- Я уже знаком с тем, как использовать синтаксис LINQ для группировки по значению, например (для группировки продаж по идентификатору клиента), однако я в недоумении, как выразить "chunking" чисто/элегантно, используя LINQ. Я не уверен, что это возможно даже простым способом.
- Я могу и уже реализовали решение в простом старом-C# без использования синтаксиса LINQ. Таким образом, моя проблема не блокируется по этому вопросу, а скорее я ищу способы выразить ее в LINQ (снова чисто и элегантно)
4 ответов
вы можете сгруппировать их по (index / chunkSize). Пример:
var result =
from i in array.Select((value, index) => new { Value = value, Index = index })
group i.Value by i.Index / chunkSize into g
select g;
для тех, кто предпочитает методы LINQ (с лямбда-выражениями), вот это ответ Дмитрия Матвеева преобразовать:
var result = array
.Select((value, index) => new { Value = value, Index = index })
.GroupBy(i => i.Index / chunkSize, v => v.Value);
Если вам нужен только массив value
, вместо IGrouping<T1, T2>
, затем добавьте следующее:
.Select(x => x.ToArray())
чтобы сделать фактическую группировку, не должно быть:
var result = array
.Select((value, index) => new { Value = value, Index = index})
.GroupBy(i => i.Index / chunk, v => v.Value);
метод расширения (через Джесси!--5-->):
public static IEnumerable<T[]> GroupToChunks<T>(this IEnumerable<T> items, int chunkSize)
{
if (chunkSize <= 0)
{
throw new ArgumentException("Chunk size must be positive.", "chunkSize");
}
return
items.Select((item, index) => new { item, index })
.GroupBy(pair => pair.index / chunkSize, pair => pair.item)
.Select(grp => grp.ToArray());
}