markzzz
markzzz

Reputation: 47947

checking for the last element in a foreach

I have this code :

foreach (Object element in elements.under)
{
    ...
}

and I'd like to print some only when I'm into the last cycle. How can I do it?

Upvotes: 8

Views: 23610

Answers (5)

KyleMit
KyleMit

Reputation: 29829

Extensible Solution

Borrowing from python's enumerate function, you can wrap a collection and return a tuple of values, containing the actual item along with any extra helpful data

Here's a simple extension method that returns the item, it's index, and if it's the first / last item.

public static class ListExtensions
{
    public static IEnumerable<(T element, int index, bool isFirst, bool isLast)> Enumerate<T>(this IEnumerable<T> list) {
        var len = list.Count();     
        return list.Select((el, i) => (el, i, i == 0, i == len - 1));
    }
}

Then you can use it like this:

var list = new[] {'A','B','C'};
foreach(var (el, i, isFirst, isLast) in list.Enumerate()) {
    Console.WriteLine($"el={el}, i={i}, isFirst={isFirst}, isLast={isLast}");
}

// el=A, i=0, isFirst=True,  isLast=False
// el=B, i=1, isFirst=False, isLast=False
// el=C, i=2, isFirst=False, isLast=True

Optimized Solution

The previous solution technically loops over the list twice (to get the length and return each item). For a minor performance improvement, you can check for the last item by looping over the enumerator like this:

public static class ListExtensions
{
    public static IEnumerable<(T element, bool isFirst, bool isLast)> Enumerate<T>(this IEnumerable<T> collection) {
        using var enumerator = collection.GetEnumerator();
        var isFirst = true;
        var isLast = !enumerator.MoveNext();

        while (!isLast)
        {
            var current = enumerator.Current;        
            isLast = !enumerator.MoveNext();

            yield return (current, isFirst, isLast);
            
            isFirst = false;
        }
    }
}

And then use like this:

var list = new[] {'A','B','C'};
foreach(var (el, isFirst, isLast) in list.Enumerate()) {
    Console.WriteLine($"el={el}, isFirst={isFirst}, isLast={isLast}");
}

// el=A, isFirst=True,  isLast=False
// el=B, isFirst=False, isLast=False
// el=C, isFirst=False, isLast=True

Demo in DotNet Fiddle

Further Reading

Upvotes: 1

Pranay Rana
Pranay Rana

Reputation: 176886

Adapted from this post on Enumerating with extra info in the Miscellaneous Utility Library

foreach (SmartEnumerable<string>.Entry entry in new SmartEnumerable<string>(list))
{
    Console.WriteLine ("{0,-7} {1} ({2}) {3}",
                        entry.IsLast  ? "Last ->" : "",
                        entry.Value,
                        entry.Index,
                        entry.IsFirst ? "<- First" : "");
}

See Also: How do you find the last loop in a For Each (VB.NET)?

Upvotes: 3

Sayed M. Idrees
Sayed M. Idrees

Reputation: 1408

You can try this simple code

foreach (object obj in allObjects)
{ 
    if (obj  != allObjects.Last())
    {
            // Do some cool stufff..
    } else
    {
            // Go Normal Way
    }
}

Upvotes: 0

Rio Stephen
Rio Stephen

Reputation: 245

You can try this:

foreach (Object element in elements.under)
{
    if (element  == elements.under.Last())  
    {
        //Print Code
    }
    else
    {
        //Do other thing here
    }
}

Upvotes: 9

Sachin Shanbhag
Sachin Shanbhag

Reputation: 55479

You need to keep track of a counter and then check for last element -

int i = 1;
foreach (Object element in elements.under)
{
    if (i == elements.under.Count) //Use count or length as supported by your collection
    { 
      //last element 
    }
    else 
    { i++; }
}

Upvotes: 8

Related Questions