Ivan-Mark Debono
Ivan-Mark Debono

Reputation: 16290

How to iterate a loop every n items

I have a list of items and I need to loop through it so that every n (eg. 3) items are first collected and then processed at once at the n'th item.

I'm doing the following:

List<MyObject> smallList = new List<MyObject>();

for (int i = 0; i < largeList.Count; i++)
{
    smallList.Add(largeList[i]);

    if (i % 3 == 0 || i >= largeList.Count - 3)
    {
        //Do somehting with those n items...
    }

    smallList.Clear();
 }

Is there a better way to do the above?

Upvotes: 6

Views: 9985

Answers (4)

Amit
Amit

Reputation: 46323

You can do it with LINQ.

First, "attach" an index to each item:

var indexedItems = largeList.Select((item, index) => new {index, item});

Now group them by their index, while selecting the collection (IEnumerable) of items for each group member:

var groupedItems = indexedItems.GroupBy(indexedItem => indexedItem.index / 3,
                   indexedItem => indexedItem.item,
                   (key, items) => items);

Now process each group

foreach(var items in groupedItems) {
  // and optionally, .ToList() to have a List<T> instead of IEnumerable<T>
  var itemsList = items.ToList();
}

And altogether...:

var indexedItems = largeList.Select((item, index) => new {index, item});
var groupedItems = indexedItems.GroupBy(indexedItem => indexedItem.index / 3,
                   indexedItem => indexedItem.item,
                   (key, items) => items);

foreach(var items in groupedItems) {
  // Use the items...
}

Upvotes: 2

kagelos
kagelos

Reputation: 423

You can also do this with LINQ:

var largeList = new List<int>(new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
for (int i = 0; i < largeList.Count; i += 3)
{
    var items = largeList.Skip(i).Take(3).ToList();
    // do stuff with your 3 (or less items)
}

Upvotes: 12

Kahbazi
Kahbazi

Reputation: 15005

you can use this code:

var MyObjectList = new List<MyObject>();

MyObjectList.Where(a => MyObjectList.IndexOf(a) % 3 == 0).ToList().ForEach(a => 
{
        // do your things!
});

Upvotes: 0

Toxantron
Toxantron

Reputation: 2398

I suggest using nested loops. Not as pretty as LinQ, but certainly faster.

const int n = 3;
var small = new List();
for(var i=0; i<large.Count; i+=n)
{
    small.Clear();
    for(var j=i; j < n && j<large.Count; j++)
        small.Add(large[j]);
    // Do stuff with small
}

However quite similar to what you have now. I think it doesn't get much butter than what you have.

Upvotes: 1

Related Questions