Coder Perfect

Determine which iteration of the loop is the final in the foreach loop.

Problem

I have a foreach loop and need to run some logic when the last item from the List is selected, for example:

 foreach (Item result in Model.Results)
 {
      //if current result is the last item in Model.Results
      //then do something in the code
 }

Is it possible to determine which loop is the last without using for loop and counters?

Asked by mishap

Solution #1

If you only need to do something with the last element (rather than something different with it), LINQ will come in handy:

Item last = Model.Results.Last();
// do something with last

You’ll need something like this if you need to do something different with the last element:

Item last = Model.Results.Last();
foreach (Item result in Model.Results)
{
    // do something with each item
    if (result.Equals(last))
    {
        // do something different with the last item
    }
    else
    {
        // do something different with every item but the last
    }
}

Though you’d almost certainly need to write your own comparer to check that the item was the same as the one returned by Last ().

Last may have to cycle through the collection, therefore this method should be used with caution. While this may not be a concern for small collections, it may have performance implications if they get huge. If the list contains duplicate items, it will likewise fail. Something like this could be more appropriate in this case:

int totalCount = result.Count();
for (int count = 0; count < totalCount; count++)
{
    Item result = Model.Results[count];

    // do something with each item
    if ((count + 1) == totalCount)
    {
        // do something different with the last item
    }
    else
    {
        // do something different with every item but the last
    }
}

Answered by ChrisF

Solution #2

Why not try a good old-fashioned for loop?

for (int i = 0; i < Model.Results.Count; i++) {

     if (i == Model.Results.Count - 1) {
           // this is the last item
     }
}

Alternatively, you might use Linq and the foreach method:

foreach (Item result in Model.Results)   
{   
     if (Model.Results.IndexOf(result) == Model.Results.Count - 1) {
             // this is the last item
     }
}

Answered by Fiona – myaccessible.website

Solution #3

When you use Last() on some types, it will cycle through the entire collection! In other words, if you do a foreach and then call Last(), you’ve looped twice! which I’m sure you’d prefer to stay away from in large collections.

Then a do while loop is the way to go:

using var enumerator = collection.GetEnumerator();

var last = !enumerator.MoveNext();
T current;

while (!last)
{
  current = enumerator.Current;        

  //process item

  last = !enumerator.MoveNext();        
  if(last)
  {
    //additional processing for last item
  }
}

The Last() function will run through all collection elements unless the collection type is of type IListT>.

Test

You can also check your item as follows if your collection offers random access (e.g., implements IListT>).

if(collection is IList<T> list)
  return collection[^1]; //replace with collection.Count -1 in pre-C#8 apps

Answered by Shimmy Weitzhandler

Solution #4

Linq will work, as Chris demonstrates; simply use Last() to get a reference to the last one in the enumerable, and do your normal code if you aren’t working with that reference; if you ARE working with that reference, do your extra thing. Its disadvantage is that it is always O(N)-complex.

Instead, you can combine your foreach with a counter and use Count() (which is O(1) if the IEnumerable is also an ICollection; this is true for most of the common built-in IEnumerables):

var i=0;
var count = Model.Results.Count();
foreach (Item result in Model.Results)
{
    if (++i == count) //this is the last item
}

Answered by KeithS

Solution #5

var last = objList.LastOrDefault();
foreach (var item in objList)
{
  if (item.Equals(last))
  {

  }
}

Answered by Gabriel Tiburcio

Post is based on https://stackoverflow.com/questions/7476174/foreach-loop-determine-which-is-the-last-iteration-of-the-loop