2016-10-11 2 views
1

Использование LINQ (или morelinq), как разделить массив неизвестной длины (но небольшой) на четные множества с меньшими (неравномерными) наборами в конце, но поддерживать порядок в каждом списке ?Сделать (в основном) наборы равной длины

var array = new int[] {1,2,3,4}; var sets = array.something(3); Ищете результат: {1,2},{3},{4}

{1} -> {1},{},{} 
{1,2} -> {1},{2},{} 
{1,2,3} -> {1},{2},{3} 
{1,2,3,4} -> {1,2},{3},{4} 
{1,2,3,4,5} -> {1,2},{3,4},{5} 
{1,2,3,4,5,6} -> {1,2},{3,4},{5,6} 

Мой исходный код:

const int MaxPerColumn = 6; 
var perColumn = (list.Count + columnCount - 1)/columnCount; 
for (var col = 1; col <= columnCount; col++) 
{ 
    var items = list.Skip((col - 1) * columnCount).Take(perColumn).Pad(MaxPerColumn, "").ToList(); 

    // DoSomething 
} 

, который не работает, потому что со списком {1,2,3,4} это создало {1,2},{3,4},{}

+0

, то почему {1,2,3.4} будет {1,2}, {3}, {4} и {1,2,3,4,5,6} быть {1,2}, {3, 4 }, {5,6}. Шаблон не выстраивается в линию? – Dispersia

+0

Я думаю, вы должны прямо указать, что ваши примеры предназначены для создания 3-х групп. –

+0

Что вы пытались сделать? Какие проблемы у вас возникли с вашей реализацией? – Servy

ответ

1

Я предлагаю не с помощью Linq здесь, но IEnumerator<T>, даже не IEnumerable<T> в реализации:

public static IEnumerable<T[]> Something<T>(this IEnumerable<T> source, int count) { 
    if (null == source) 
    throw new ArgumentNullException("source"); 
    else if (count <= 0) 
    throw new ArgumentOutOfRangeException("count"); 

    int c = source.Count(); 
    int size = c/count + (c % count > 0 ? 1 : 0); 
    int large = count - count * size + c;  

    using (var en = source.GetEnumerator()) { 
    for (int i = 0; i < count; ++i) { 
     T[] chunk = new T[i < large ? size : size - 1]; 

     for (int j = 0; j < chunk.Length; ++j) { 
     en.MoveNext(); 

     chunk[j] = en.Current; 
     } 

     yield return chunk; 
    } 
    } 
} 

....

var array = new int[] { 1, 2, 3, 4 }; 

string result = string.Join(", ", array 
    .Something(5) 
    .Select(item => $"[{string.Join(", ", item)}]")); 

// [1], [2], [3], [4], [] 
Console.Write(result); 
Смежные вопросы