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());
}