263

I have a foreach loop and need to execute some logic when the last item is chosen from the List, e.g.:

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

Can I know which loop is last without using for loop and counters?

ChrisF
  • 127,439
  • 29
  • 243
  • 315
mishap
  • 7,133
  • 14
  • 56
  • 89
  • 1
    Take a look at my answer [here](http://stackoverflow.com/a/3293486/158779) for a solution I posted to a related question. – Brian Gideon Jul 08 '13 at 01:14
  • Related: *[How do you get the index of the current iteration of a foreach loop?](http://stackoverflow.com/questions/43021)* – Peter Mortensen Jul 28 '15 at 12:12

26 Answers26

327

If you just need to do something with the last element (as opposed to something different with the last element then using LINQ will help here:

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

If you need to do something different with the last element then you'd need something like:

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 probably need to write a custom comparer to ensure that you could tell that the item was the same as the item returned by Last().

This approach should be used with caution as Last may well have to iterate through the collection. While this might not be a problem for small collections, if it gets large it could have performance implications. It will also fail if the list contains duplicate items. In this cases something like this may be more appropriate:

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
    }
}
ChrisF
  • 127,439
  • 29
  • 243
  • 315
  • 1
    What I needed was : When the loop is going trough its last item : foreach (Item result in Model.Results) { if (result == Model.Results.Last()) {
    last
    ; } Seems that you pretty much meant same thing.
    – mishap Sep 19 '11 at 19:38
  • 10
    You code will iterate twice thru the entire collection - bad if the collection isn't small. See [this](http://stackoverflow.com/a/17460853/75500) answer. – Shimmy Weitzhandler Jul 04 '13 at 02:18
  • 59
    This doesn't really work if you have duplicates in your collection. For example, if you're working with a collection of strings, and there are any duplicates, then that "different with the last item" code will execute for every occurrence of the last item in the list. – muttley91 Sep 27 '13 at 18:22
  • 7
    This answer is old, but for others looking at this answer, you can get the last element and ensure you do not have to loop through the elements by using: Item last = Model.Results[Model.Results.Count - 1] The count property of a list does not require looping. If you have duplicates in your list, then just use an iterator variable in a for loop. Regular old for loops are not bad. – Michael Harris Jan 07 '15 at 19:45
  • I suggest to using `var last = Model.Result[Model.Result.Count - 1];` for faster than using `Last()` – Tân Nov 25 '16 at 07:52
  • this will only work if list/collection has unique values. – melleck Feb 21 '19 at 12:36
203

How about 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
     }
}

Or using Linq and the foreach:

foreach (Item result in Model.Results)   
{   
     if (Model.Results.IndexOf(result) == Model.Results.Count - 1) {
             // this is the last item
     }
}
Fiona - myaccessible.website
  • 13,581
  • 15
  • 77
  • 114
  • 17
    So many ppl overthinking a simple problem like this, when the for loop is perfectly capable of doing it already. :\ – Andrew Hoffman Oct 14 '15 at 16:33
  • The Linq solution is my absolute favorite! Thanks for sharing – mecograph Apr 12 '19 at 13:38
  • This is the more appropriate answer than the accepted one. – Ratul Aug 23 '19 at 08:42
  • 2
    Note to anyone wanting to use the LINQ solution on a collection of strings (or value types): It generally won't work because the == comparison will fail if the last string in the list also appears earlier in the list. It would only work if you're working with a list guaranteed to have no duplicate strings. – Tawab Wakil Apr 06 '20 at 21:22
  • 1
    Unfortunately you cannot use this clever solution if `Model.Results` is an `IEnumerable`. You can call `Count()` before the loop but that may cause the full iteration of the sequence. – Luca Cremonesi Apr 17 '20 at 00:12
48

As Chris shows, Linq will work; just use Last() to get a reference to the last one in the enumerable, and as long as you aren't working with that reference then do your normal code, but if you ARE working with that reference then do your extra thing. Its downside is that it will always be O(N)-complexity.

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

var i=0;
var count = Model.Results.Count();
foreach (Item result in Model.Results)
{
    if (++i == count) //this is the last item
}
Shimmy Weitzhandler
  • 92,920
  • 119
  • 388
  • 596
KeithS
  • 65,745
  • 16
  • 102
  • 161
47

Using Last() on certain types will loop thru the entire collection!
Meaning that if you make a foreach and call Last(), you looped twice! which I'm sure you'd like to avoid in big collections.

Then the solution is to use a do while loop:

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
  }
}

So unless the collection type is of type IList<T> the Last() function will iterate thru all collection elements.

Test

If your collection provides random access (e.g. implements IList<T>), you can also check your item as follows.

if(collection is IList<T> list)
  return collection[^1]; //replace with collection.Count -1 in pre-C#8 apps
Shimmy Weitzhandler
  • 92,920
  • 119
  • 388
  • 596
  • 1
    Are you sure that the enumerator needs a `using` statement? I thought that's only needed if an object handles operating system resources, but not for managed data structures. – Crouching Kitten Jan 11 '20 at 13:02
  • 1
    IEnumerator doesn't implement IDisposable, so the line with using with raise a compile time error! +1 for the solution , most of the time we can't just simply use a for instead of foreach , because enumerable collections items calculate at runtime or the sequence doesn't support random access. – Saleh Jan 20 '20 at 12:13
  • 1
    The [generic one](https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerator-1?view=netstandard-1.0) does. – Shimmy Weitzhandler Jan 21 '20 at 13:05
22
var last = objList.LastOrDefault();
foreach (var item in objList)
{
  if (item.Equals(last))
  {
  
  }
}
Shimmy Weitzhandler
  • 92,920
  • 119
  • 388
  • 596
  • Hello, this one is the best approach so far! Simple and to the point. An programmer-thingking approach, one. Why dont we choose and give this one +1 more and more! – Hanny Setiawan Feb 03 '17 at 12:26
  • 1
    The last item should be found only once (***Promote memoization***) before `foreach` block. Like this: `var lastItem = objList.LastOrDeafault();`. Then from the inside of `foreach` loop you could check it this way: `f (item.Equals(lastItem)) { ... }`. In your original answer the `objList.LastOrDefault()` would iterate over the collection at each "foreach" iteration (***Polinomial complexity is involved***). – AlexMelw Mar 22 '18 at 14:57
  • 2
    Bad answer. n^2 complexity instead of n. – Shimmy Weitzhandler Jan 31 '20 at 10:07
  • 1
    This is incorrect because of issue @ShimmyWeitzhandler mentioned and should not be used. All such values for statements usually expected to be prepared outside of loop. – F8ER Oct 12 '20 at 01:40
  • I've updated the answer to avoid people from that pitfall. – Shimmy Weitzhandler Oct 12 '20 at 09:15
12

As Shimmy has pointed out, using Last() can be a performance problem, for instance if your collection is the live result of a LINQ expression. To prevent multiple iterations, you could use a "ForEach" extension method like this:

var elements = new[] { "A", "B", "C" };
elements.ForEach((element, info) => {
    if (!info.IsLast) {
        Console.WriteLine(element);
    } else {
        Console.WriteLine("Last one: " + element);
    }
});

The extension method looks like this (as an added bonus, it will also tell you the index and if you're looking at the first element):

public static class EnumerableExtensions {
    public delegate void ElementAction<in T>(T element, ElementInfo info);

    public static void ForEach<T>(this IEnumerable<T> elements, ElementAction<T> action) {
        using (IEnumerator<T> enumerator = elements.GetEnumerator())
        {
            bool isFirst = true;
            bool hasNext = enumerator.MoveNext();
            int index = 0;
            while (hasNext)
            {
                T current = enumerator.Current;
                hasNext = enumerator.MoveNext();
                action(current, new ElementInfo(index, isFirst, !hasNext));
                isFirst = false;
                index++;
            }
        }
    }

    public struct ElementInfo {
        public ElementInfo(int index, bool isFirst, bool isLast)
            : this() {
            Index = index;
            IsFirst = isFirst;
            IsLast = isLast;
        }

        public int Index { get; private set; }
        public bool IsFirst { get; private set; }
        public bool IsLast { get; private set; }
    }
}
AlexMelw
  • 1,757
  • 18
  • 33
Daniel Wolf
  • 10,328
  • 9
  • 42
  • 73
9

Improving Daniel Wolf answer even further you could stack on another IEnumerable to avoid multiple iterations and lambdas such as:

var elements = new[] { "A", "B", "C" };
foreach (var e in elements.Detailed())
{
    if (!e.IsLast) {
        Console.WriteLine(e.Value);
    } else {
        Console.WriteLine("Last one: " + e.Value);
    }
}

The extension method implementation:

public static class EnumerableExtensions {
    public static IEnumerable<IterationElement<T>> Detailed<T>(this IEnumerable<T> source)
    {
        if (source == null)
            throw new ArgumentNullException(nameof(source));

        using (var enumerator = source.GetEnumerator())
        {
            bool isFirst = true;
            bool hasNext = enumerator.MoveNext();
            int index = 0;
            while (hasNext)
            {
                T current = enumerator.Current;
                hasNext = enumerator.MoveNext();
                yield return new IterationElement<T>(index, current, isFirst, !hasNext);
                isFirst = false;
                index++;
            }
        }
    }

    public struct IterationElement<T>
    {
        public int Index { get; }
        public bool IsFirst { get; }
        public bool IsLast { get; }
        public T Value { get; }

        public IterationElement(int index, T value, bool isFirst, bool isLast)
        {
            Index = index;
            IsFirst = isFirst;
            IsLast = isLast;
            Value = value;
        }
    }
}
Fabricio Godoy
  • 459
  • 5
  • 8
  • 1
    The other answer doesn't iterate the source multiple times, so that's not a problem you're fixing. You have indeed allowed the use of `foreach`, which is an improvement. – Servy Jul 27 '17 at 15:42
  • 1
    @Servy I mean that. Besides single iteration from original answer I'm avoiding lambdas. – Fabricio Godoy Jul 27 '17 at 18:21
7

The iterator implementation does not provide that. Your collection might be an IList that is accessible via an index in O(1). In that case you can use a normal for-loop:

for(int i = 0; i < Model.Results.Count; i++)
{
  if(i == Model.Results.Count - 1) doMagic();
}

If you know the count, but cannot access via indices (thus, result is an ICollection), you can count yourself by incrementing an i in the foreach's body and comparing it to the length.

All this isn't perfectly elegant. Chris's solution may be the nicest I've seen so far.

Matthias Meid
  • 12,080
  • 6
  • 41
  • 73
  • In comparing performance of your counter within the foreach idea vs Chris' solution, I wonder which would cost more- a single Last() call, or the sum of all the added increment operations. I suspect it would be close. – TTT Jan 06 '14 at 23:00
6

What about little simpler approach.

Item last = null;
foreach (Item result in Model.Results)
{
    // do something with each item

    last = result;
}

//Here Item 'last' contains the last object that came in the last of foreach loop.
DoSomethingOnLastElement(last);
Community
  • 1
  • 1
faisal
  • 99
  • 1
  • 4
  • 2
    I don't know why someone down-voted you. This is perfectly acceptable considering you are already performing a foreach and are incurring the cost of o(n). – arviman Aug 27 '15 at 07:03
  • 2
    Despite the fact that the answer is perfect for finding out the last item, **it doesn't suit the OP's condition** "*..., determine which is the last iteration of the loop*". So, you're not able to determine that the last iteration is actually the last one, and, thus, you couldn't handle it differently or even ignoring it. That's the reason someone has downvoted you. @arviman you were so curious about it. – AlexMelw Mar 22 '18 at 14:39
  • 1
    You're right, I totally missed it @Andrey-WD. I guess the solution to fix is to call "last" once before the loop (can't do it inside the loop as it would be O(N^2) and then check if the reference matches it. – arviman Mar 26 '18 at 06:34
5

The best approach would probably be just to execute that step after the loop: e.g.

foreach(Item result in Model.Results)
{
   //loop logic
}

//Post execution logic

Or if you need to do something to the last result

foreach(Item result in Model.Results)
{
   //loop logic
}

Item lastItem = Model.Results[Model.Results.Count - 1];

//Execute logic on lastItem here
Dustin Hodges
  • 4,080
  • 3
  • 23
  • 41
3

The accepted answer will not work for duplicates in the collection. If you're set on the foreach, you can just add your own indexing variable(s).

int last = Model.Results.Count - 1;
int index = 0;
foreach (Item result in Model.Results)
{
    //Do Things

    if (index == last)
        //Do Things with the last result

    index++;
}
Ehryk
  • 1,781
  • 2
  • 24
  • 46
2

using Linq and the foreach:

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

https://code.i-harness.com/en/q/7213ce

1

".Last()" didnt work for me, so I had to do something like this:

Dictionary<string, string> iterativeDictionary = someOtherDictionary;
var index = 0;
iterativeDictionary.ForEach(kvp => 
    index++ == iterativeDictionary.Count ? 
        /*it's the last item */ :
        /*it's not the last item */
);
itcropper
  • 696
  • 1
  • 5
  • 21
1

Making some small adjustments to the excelent code of Jon Skeet, you can even make it smarter by allowing access to the previous and next item. Of course this means you'll have to read ahead 1 item in the implementation. For performance reasons, the previous and next item are only retained for the current iteration item. It goes like this:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
// Based on source: http://jonskeet.uk/csharp/miscutil/

namespace Generic.Utilities
{
    /// <summary>
    /// Static class to make creation easier. If possible though, use the extension
    /// method in SmartEnumerableExt.
    /// </summary>
    public static class SmartEnumerable
    {
        /// <summary>
        /// Extension method to make life easier.
        /// </summary>
        /// <typeparam name="T">Type of enumerable</typeparam>
        /// <param name="source">Source enumerable</param>
        /// <returns>A new SmartEnumerable of the appropriate type</returns>
        public static SmartEnumerable<T> Create<T>(IEnumerable<T> source)
        {
            return new SmartEnumerable<T>(source);
        }
    }

    /// <summary>
    /// Type chaining an IEnumerable&lt;T&gt; to allow the iterating code
    /// to detect the first and last entries simply.
    /// </summary>
    /// <typeparam name="T">Type to iterate over</typeparam>
    public class SmartEnumerable<T> : IEnumerable<SmartEnumerable<T>.Entry>
    {

        /// <summary>
        /// Enumerable we proxy to
        /// </summary>
        readonly IEnumerable<T> enumerable;

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="enumerable">Collection to enumerate. Must not be null.</param>
        public SmartEnumerable(IEnumerable<T> enumerable)
        {
            if (enumerable == null)
            {
                throw new ArgumentNullException("enumerable");
            }
            this.enumerable = enumerable;
        }

        /// <summary>
        /// Returns an enumeration of Entry objects, each of which knows
        /// whether it is the first/last of the enumeration, as well as the
        /// current value and next/previous values.
        /// </summary>
        public IEnumerator<Entry> GetEnumerator()
        {
            using (IEnumerator<T> enumerator = enumerable.GetEnumerator())
            {
                if (!enumerator.MoveNext())
                {
                    yield break;
                }
                bool isFirst = true;
                bool isLast = false;
                int index = 0;
                Entry previous = null;

                T current = enumerator.Current;
                isLast = !enumerator.MoveNext();
                var entry = new Entry(isFirst, isLast, current, index++, previous);                
                isFirst = false;
                previous = entry;

                while (!isLast)
                {
                    T next = enumerator.Current;
                    isLast = !enumerator.MoveNext();
                    var entry2 = new Entry(isFirst, isLast, next, index++, entry);
                    entry.SetNext(entry2);
                    yield return entry;

                    previous.UnsetLinks();
                    previous = entry;
                    entry = entry2;                    
                }

                yield return entry;
                previous.UnsetLinks();
            }
        }

        /// <summary>
        /// Non-generic form of GetEnumerator.
        /// </summary>
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        /// <summary>
        /// Represents each entry returned within a collection,
        /// containing the value and whether it is the first and/or
        /// the last entry in the collection's. enumeration
        /// </summary>
        public class Entry
        {
            #region Fields
            private readonly bool isFirst;
            private readonly bool isLast;
            private readonly T value;
            private readonly int index;
            private Entry previous;
            private Entry next = null;
            #endregion

            #region Properties
            /// <summary>
            /// The value of the entry.
            /// </summary>
            public T Value { get { return value; } }

            /// <summary>
            /// Whether or not this entry is first in the collection's enumeration.
            /// </summary>
            public bool IsFirst { get { return isFirst; } }

            /// <summary>
            /// Whether or not this entry is last in the collection's enumeration.
            /// </summary>
            public bool IsLast { get { return isLast; } }

            /// <summary>
            /// The 0-based index of this entry (i.e. how many entries have been returned before this one)
            /// </summary>
            public int Index { get { return index; } }

            /// <summary>
            /// Returns the previous entry.
            /// Only available for the CURRENT entry!
            /// </summary>
            public Entry Previous { get { return previous; } }

            /// <summary>
            /// Returns the next entry for the current iterator.
            /// Only available for the CURRENT entry!
            /// </summary>
            public Entry Next { get { return next; } }
            #endregion

            #region Constructors
            internal Entry(bool isFirst, bool isLast, T value, int index, Entry previous)
            {
                this.isFirst = isFirst;
                this.isLast = isLast;
                this.value = value;
                this.index = index;
                this.previous = previous;
            }
            #endregion

            #region Methods
            /// <summary>
            /// Fix the link to the next item of the IEnumerable
            /// </summary>
            /// <param name="entry"></param>
            internal void SetNext(Entry entry)
            {
                next = entry;
            }

            /// <summary>
            /// Allow previous and next Entry to be garbage collected by setting them to null
            /// </summary>
            internal void UnsetLinks()
            {
                previous = null;
                next = null;
            }

            /// <summary>
            /// Returns "(index)value"
            /// </summary>
            /// <returns></returns>
            public override string ToString()
            {
                return String.Format("({0}){1}", Index, Value);
            }
            #endregion

        }
    }
}
Edwin
  • 489
  • 4
  • 15
1

How to convert foreach to react to the last element:

List<int> myList = new List<int>() {1, 2, 3, 4, 5};
Console.WriteLine("foreach version");
{
    foreach (var current in myList)
    {
        Console.WriteLine(current);
    }
}
Console.WriteLine("equivalent that reacts to last element");
{
    var enumerator = myList.GetEnumerator();
    if (enumerator.MoveNext() == true) // Corner case: empty list.
    {
        while (true)
        {
            int current = enumerator.Current;

            // Handle current element here.
            Console.WriteLine(current);

            bool ifLastElement = (enumerator.MoveNext() == false);
            if (ifLastElement)
            {
                // Cleanup after last element
                Console.WriteLine("[last element]");
                break;
            }
        }
    }
    enumerator.Dispose();
}
Contango
  • 65,385
  • 53
  • 229
  • 279
1

Just store the previous value and work with it inside the loop. Then at the end the 'previous' value will be the last item, letting you handle it differently. No counting or special libraries required.

bool empty = true;
Item previousItem;

foreach (Item result in Model.Results)
{
    if (!empty)
    {
        // We know this isn't the last item because it came from the previous iteration
        handleRegularItem(previousItem);
    }

    previousItem = result;
    empty = false;
}

if (!empty)
{
    // We know this is the last item because the loop is finished
    handleLastItem(previousItem);
}
voltrevo
  • 8,223
  • 3
  • 23
  • 25
1

You could just use a for loop and there is no need to add an extra if inside the for body:

for (int i = 0; i < Model.Results.Count - 1; i++) {
    var item = Model.Results[i];
}

The -1 in the for condition takes care of skipping the last item.

Alisson
  • 6,940
  • 3
  • 46
  • 65
  • The -1 in the for loop doesn't take care of skipping the last item. You would get an IndexOutOfRangeException if you didn't include the -1. – Jaa H May 11 '20 at 09:32
1

Based on @Shimmy's response, I created an extension method that is the solution that everyone wants. It is simple, easy to use, and only loops through the collection once.

internal static class EnumerableExtensions
{
    public static void ForEachLast<T>(this IEnumerable<T> collection, Action<T>? actionExceptLast = null, Action<T>? actionOnLast = null)
    {
        using var enumerator = collection.GetEnumerator();
        var isNotLast = enumerator.MoveNext();
        while (isNotLast)
        {
            var current = enumerator.Current;
            isNotLast = enumerator.MoveNext();
            var action = isNotLast ? actionExceptLast : actionOnLast;
            action?.Invoke(current);
        }
    }
}

This works on any IEnumerable<T>. Usage looks like this:

var items = new[] {1, 2, 3, 4, 5};
items.ForEachLast(i => Console.WriteLine($"{i},"), i => Console.WriteLine(i));

Output looks like:

1,
2,
3,
4,
5

Additionally, you can make this into a Select style method. Then, reuse that extension in the ForEach. That code looks like this:

internal static class EnumerableExtensions
{
    public static void ForEachLast<T>(this IEnumerable<T> collection, Action<T>? actionExceptLast = null, Action<T>? actionOnLast = null) =>
        // ReSharper disable once IteratorMethodResultIsIgnored
        collection.SelectLast(i => { actionExceptLast?.Invoke(i); return true; }, i => { actionOnLast?.Invoke(i); return true; }).ToArray();

    public static IEnumerable<TResult> SelectLast<T, TResult>(this IEnumerable<T> collection, Func<T, TResult>? selectorExceptLast = null, Func<T, TResult>? selectorOnLast = null)
    {
        using var enumerator = collection.GetEnumerator();
        var isNotLast = enumerator.MoveNext();
        while (isNotLast)
        {
            var current = enumerator.Current;
            isNotLast = enumerator.MoveNext();
            var selector = isNotLast ? selectorExceptLast : selectorOnLast;
            //https://stackoverflow.com/a/32580613/294804
            if (selector != null)
            {
                yield return selector.Invoke(current);
            }
        }
    }
}
Michael Yanni
  • 1,286
  • 3
  • 15
  • 26
0

Jon Skeet created a SmartEnumerable<T> type a while back to solve this exact issue. You can see it's implementation here:

http://codeblog.jonskeet.uk/2007/07/27/smart-enumerations/

To download: http://www.yoda.arachsys.com/csharp/miscutil/

Spencer Ruport
  • 34,215
  • 11
  • 81
  • 141
0

To do something additional to each element except for the last one, function based approach can be used.

delegate void DInner ();

....
    Dinner inner=delegate 
    { 
        inner=delegate 
        { 
            // do something additional
        } 
    }
    foreach (DataGridViewRow dgr in product_list.Rows)
    {
        inner()
        //do something
    }
}

This approach has apparent drawbacks: less code clarity for more complex cases. Calling delegates might be not very effective. Troubleshooting might be not quite easy. The bright side - coding is fun!

Having said that, I would suggest using plain for loops in trivial cases, if you know that your collection's count is not terribly slow.

dmitry
  • 148
  • 1
  • 9
0

Another way, which I didn't see posted, is to use a Queue. It's analogous to a way to implement a SkipLast() method without iterating more than necessary. This way will also allow you to do this on any number of last items.

public static void ForEachAndKnowIfLast<T>(
    this IEnumerable<T> source,
    Action<T, bool> a,
    int numLastItems = 1)
{
    int bufferMax = numLastItems + 1;
    var buffer = new Queue<T>(bufferMax);
    foreach (T x in source)
    {
        buffer.Enqueue(x);
        if (buffer.Count < bufferMax)
            continue; //Until the buffer is full, just add to it.
        a(buffer.Dequeue(), false);
    }
    foreach (T item in buffer)
        a(item, true);
}

To call this you'd do the following:

Model.Results.ForEachAndKnowIfLast(
    (result, isLast) =>
    {
        //your logic goes here, using isLast to do things differently for last item(s).
    });
rrreee
  • 610
  • 5
  • 17
0
     List<int> ListInt = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };


                int count = ListInt.Count;
                int index = 1;
                foreach (var item in ListInt)
                {
                    if (index != count)
                    {
                        Console.WriteLine("do something at index number  " + index);
                    }
                    else
                    {
                        Console.WriteLine("Foreach loop, this is the last iteration of the loop " + index);
                    }
                    index++;

                }
 //OR
                int count = ListInt.Count;
                int index = 1;
                foreach (var item in ListInt)
                {
                    if (index < count)
                    {
                        Console.WriteLine("do something at index number  " + index);
                    }
                    else
                    {
                        Console.WriteLine("Foreach loop, this is the last iteration of the loop " + index);
                    }
                    index++;

                }
0

You can make an extension method specially dedicated to this:

public static class EnumerableExtensions {
    public static bool IsLast<T>(this List<T> items, T item)
        {
            if (items.Count == 0)
                return false;
            T last = items[items.Count - 1];
            return item.Equals(last);
        }
    }

and you can use it like this:

foreach (Item result in Model.Results)
{
    if(Model.Results.IsLast(result))
    {
        //do something in the code
    }
}
A. Morel
  • 5,749
  • 41
  • 40
-1

We can check last item in loop.

foreach (Item result in Model.Results)
{
    if (result==Model.Results.Last())
    {
        // do something different with the last item
    }
}
Bashir Momen
  • 689
  • 9
  • 14
-2
foreach (DataRow drow in ds.Tables[0].Rows)
            {
                cnt_sl1 = "<div class='col-md-6'><div class='Slider-img'>" +
                          "<div class='row'><img src='" + drow["images_path"].ToString() + "' alt='' />" +
                          "</div></div></div>";
                cnt_sl2 = "<div class='col-md-6'><div class='Slider-details'>" +
                          "<p>" + drow["situation_details"].ToString() + "</p>" +
                          "</div></div>";
                if (i == 0)
                {
                    lblSituationName.Text = drow["situation"].ToString();
                }
                if (drow["images_position"].ToString() == "0")
                {
                    content += "<div class='item'>" + cnt_sl1 + cnt_sl2 + "</div>";
                    cnt_sl1 = "";
                    cnt_sl2 = "";
                }
                else if (drow["images_position"].ToString() == "1")
                {
                    content += "<div class='item'>" + cnt_sl2 + cnt_sl1 + "</div>";
                    cnt_sl1 = "";
                    cnt_sl2 = "";
                }
                i++;
            }
-3

You can do like this :

foreach (DataGridViewRow dgr in product_list.Rows)
{
    if (dgr.Index == dgr.DataGridView.RowCount - 1)
    {
        //do something
    }
}
Community
  • 1
  • 1
Sheharyar
  • 1
  • 1