Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I know if I'm iterating on the last item of the collection?

I want to do something different on the last KeyValuePair of the Dictionary I'm iterating on.

For Each item In collection
    If ItsTheLastItem
        DoX()
    Else
        DoY()
    End If
Next 

Is this possible?

Re-Edit: I'm not using a Dictionary's values, I'm actually using a List of KeyValuePairs. I've converted them and didn't notice later, dumb me.

like image 407
Camilo Martin Avatar asked Dec 26 '10 20:12

Camilo Martin


2 Answers

I would make your own extension method. This implementation here guarantees you only walk the collection once.

static class IEnumerableExtensions {
    public static void ForEachExceptTheLast<T>(
        this IEnumerable<T> source,
        Action<T> usualAction,
        Action<T> lastAction
    ) {
        var e = source.GetEnumerator();
        T penultimate;
        T last;
        if (e.MoveNext()) {
            last = e.Current;
            while(e.MoveNext()) {
                penultimate = last;
                last = e.Current;
                usualAction(penultimate);
            }
            lastAction(last);
        }
    }
}    

Usage:

Enumerable.Range(1, 5)
          .ForEachExceptTheLast(
              x => Console.WriteLine("Not last: " + x),
              x => Console.WriteLine("Last: " + x)
);

Output:

Not last: 1
Not last: 2
Not last: 3
Not last: 4
Last: 5
like image 137
jason Avatar answered Nov 01 '22 18:11

jason


Unless you want to implement the foreach yourself, use a counter (C# code):

int count = collection.Count;
int counter = 0;

foreach(var item in collection)
{
  counter++;
  if(counter == count)
    DoX();
  else
    DoY();
}

Please note that this will only work with non-streamed IEnumerable<T>, also, depending on the implementation, Count would cause the collection to be walked twice.

like image 31
Femaref Avatar answered Nov 01 '22 19:11

Femaref