When foreach
ing through a generic list I often want to do something different for the first element in the list:
List<object> objs = new List<object>
{
new Object(),
new Object(),
new Object(),
new Object()
};
foreach (object o in objs)
{
if (o == objs.First())
{
System.Diagnostics.Debug.WriteLine("First object - do something special");
}
else
{
System.Diagnostics.Debug.WriteLine("object Do something else");
}
}
This will output:
First object - do something special object Do something else object Do something else object Do something else
This is all fine and dandy.
However if my generic list is of a value type, this approach will fail.
List<int> ints = new List<int> { 0, 0, 0, 0 };
foreach (int i in ints)
{
if (i == ints.First())
{
System.Diagnostics.Debug.WriteLine("First int - do something special");
}
else
{
System.Diagnostics.Debug.WriteLine("int Do something else");
}
}
This will output:
First int - do something special First int - do something special First int - do something special First int - do something special
Now I know I could recode this to add a boolean
flag variable or traditional for
loop, but I am wondering if there's any way to find out if a foreach loop is on the first iteration of its looping.
Using the CodeThe ForEach method of the List<T> (not IList<T> ) executes an operation for every object which is stored in the list. Normally it contains code to either read or modify every object which is in the list or to do something with list itself for every object.
Using foreach Statement The standard option to iterate over the List in C# is using a foreach loop. Then, we can perform any action on each element of the List. The following code example demonstrates its usage by displaying the contents of the list to the console.
The foreach loop works only on arrays, and is used to loop through each key/value pair in an array.
Well, you could code it using explicit iteration:
using(var iter = ints.GetEnumerator()) {
if(iter.MoveNext()) {
// do "first" with iter.Current
while(iter.MoveNext()) {
// do something with the rest of the data with iter.Current
}
}
}
The bool flag option (with foreach
) is probably easier though... that is what I (almost) always do!
Another option would be LINQ:
if(ints.Any()) {
var first = ints.First();
// do something with first
}
foreach(var item in ints.Skip(1)) {
// do something with the rest of them
}
The downside of the above is that it tries to look at the list 3 times... since we know it is a list, that is fine - but if all we had was an IEnumerable<T>
, it would only be sensible to iterate it once (since the source might not be re-readable).
A while ago I wrote SmartEnumerable (part of MiscUtil) which lets you know if the current element is the first or last, as well as its index. That may help you... it's part of MiscUtil, which is open source - you can take just SmartEnumerable under the same licence, of course.
Sample code (c'n'p from the web page):
using System;
using System.Collections.Generic;
using MiscUtil.Collections;
class Example
{
static void Main(string[] args)
{
List<string> list = new List<string>();
list.Add("a");
list.Add("b");
list.Add("c");
list.Add("d");
list.Add("e");
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" : "");
}
}
}
EDIT: Note that while it works with reference types with distinct references, it'll still fail if you give it a list where the first reference crops up elsewhere in the list.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With