Every developer uses for
and foreach
loops. To iterate a collection, foreach
is, in most cases, more convenient than a for
loop. It works with all collection types, including those that are not indexable such as IEnumerable<T>
, and doesn't require to access the current element by its index.
But sometimes, we really do need the index of the current item; this usually leads to index-handling manually or switching to a for
loop:
// foreach with a "manual" index
int index = 0;
foreach (var item in collection)
{
DoSomething(item, index);
index++;
}
// normal for loop
for (int index = 0; index < collection.Count; index++)
{
var item = collection[index];
DoSomething(item, index);
}
Couldn't we have the benefits of both foreach
and for
? It turns out that there's a simple solution, using Linq and tuples. Just write an extension method like this:
using System.Linq;
...
public static IEnumerable<(T item, int index)> WithIndex<T>(this IEnumerable<T> source)
{
return source.Select((item, index) => (item, index));
}
And now you can do this:
foreach (var (item, index) in collection.WithIndex())
{
DoSomething(item, index);
}