8

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?

0

5 Answers 5

9

You can try this:

foreach (Object element in elements.under) { if (element == elements.under.Last()) { //Print Code } else { //Do other thing here } } 
Sign up to request clarification or add additional context in comments.

1 Comment

This is bad code that can yield bad performance. If under does not support random access (i.e. implement the IList<> interface, like an array and List<> do) then Last() will have to enumerate every element of under for every iteration of the foreach.
8

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

1 Comment

@markzz - removed it long back. if your i starts with 0, then you will need -1, else ignore.
3

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)?

Comments

1

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

Comments

0

You can try this simple code

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

2 Comments

This is the same as Rio Stephen's answer and bad for the same reason: if allObjects does not support random access (i.e. implement the IList<> interface, like an array and List<> do) then Last() will have to enumerate every element of allObjects for every iteration of the foreach.
@LanceU.Matthews Well this is the only way with getting list.last();

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.