2009-08-11 6 views
7

КОНТЕКСТ

  • У меня есть список элементов (или произвольной длины). Я хотел бы сгруппировать их в «куски» определенного размера
  • Пример: у меня есть 12 клиентов [0,1,2,3,4,5,6,7,8,9,10,11] и хотите сгруппировать themin chunks из 5, которые дали бы [0,1,2,3,4] [5,6,7,8,9] [10,11]
  • ПРИМЕЧАНИЕ: На самом деле я не работаю с клиентами или монотонно увеличивая целые числа. Я взял, что только упростить задать вопрос

МОЙ ВОПРОС

Как я могу сформулировать простой LINQ запрос (с помощью синтаксиса запросов), который выполняет эту группировку?Linq: Как группы по максимальному количеству элементов

ФОН

  • Я уже знаком с тем, как использовать синтаксис LINQ для группирования значения, например (для продаж группы по идентификатору клиента), однако я в недоумении, как выразить «отрывы «чисто/элегантно, используя LINQ. Я не уверен, что это возможно даже прямо.
  • Я могу и уже реализовал решение в plain-old-C# без использования синтаксиса LINQ. Таким образом, моя проблема не блокируется по этому вопросу, но я ищу способы выразить ее в LINQ (снова чисто и элегантно).
+0

возможно дубликат [Список Split в подсписков с LINQ] (http://stackoverflow.com/questions/419019/split-list-into -sublists-with-linq) – nawfal

ответ

9

Вы можете сгруппировать их по (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; 
+1

Это один из тех редких случаев, когда простая петля и словарь короче и понятнее, чем LINQ ... – Ray

+0

@ Dimitriy - ответ для ответа @Ray - определенно – namenlos

+0

Отличное решение ! Очень полезно! –

2

Для тех, кто предпочитает методы LINQ (с лямбда-выражений), здесь Dimitriy Matveev's answer конвертирована:

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()) 
0

Чтобы сделать фактическую группировку, не должна она быть:

var result = array 
.Select((value, index) => new { Value = value, Index = index}) 
.GroupBy(i => i.Index/chunk, v => v.Value); 
+0

Стивен - ты прав. Я обновил свой ответ. Спасибо, что поймал это. Также обратите внимание, что StackOverflow (StackExchange в целом тоже) не является стилем форума, на который вы отвечаете на ответ «выше». Вы решили ответить на вопрос. Я понимаю, что у вас, вероятно, недостаточно комментариев, чтобы добавить комментарий. Так или иначе, просто пытаюсь помочь. – Jesse

0

метод расширения (с помощью Jesse's answer):

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()); 
} 
Смежные вопросы