There is often the case where you want to loop over a collection of objects along with an indicator of where you are in the loop. While some languages have a built-in syntax for expressing this C# does not (yet). Using a bit of LINQ you can easily accomplish this.
Normally starting with a collection of things you might use a for loop to iterate over list and provide your index.
For example:
var items = new List<string>();
for (int i = 0; i < items.Count; i++) {
var item = items[i];
Console.WriteLine($"Item {i}: {item}");
}
You can also use a foreach and use an temp variable to track the index.
int i = 0;
foreach (var item in items) {
Console.WriteLine($"Item {i}: {item}");
i++;
}
Recently I discovered this gem. The following code uses a Linq Select statement to transform the list into tuples containing the index and the object as named properties. Not quite as nice as if this was built-in to the language but still nice to be able to reduce the code down.
foreach (var (item, index) in items.Select((v, i) => (v, i))) {
Console.WriteLine($"Item {index}: {item}");
}
You can also add an extension method to encapsulate the Select and make it a little cleaner.
/// <summary>
/// Return the list as an enumerable of tuples with the item and it's index in the list.
/// </summary>
/// <typeparam name="T">The typeof items in the list</typeparam>
/// <param name="list">List to converted</param>
/// <returns>Enumerable of tuples with the item and it's index</returns>
public static IEnumerable<(T, int)> WithIndex<T>(this IEnumerable<T> list) =>
list.Select((value, index) => (value, index));
And then use it like this:
foreach (var (item, index) in items.WithIndex()) {
Console.WriteLine($"Item {index}: {item}");
}