Foreach loops and indexes

Using a tuple to keep track of an item index in a foreach loop

Home DailyDrop

Daily Knowledge Drop

Often when iterating through a list using a foreach loop, an index to the item's position in the list is also required - instead of using a separate index variable, a tuple can be used to keep track of the item and it's index


Manually tracking index

Sometimes while iterating, the index of the item in the list is required - usually this is done by creating a separate variable and manually increasing it in each iteration:

// list with 5 items
var list = new List<int>();
list.AddRange(Enumerable.Range(1, 5));

// variable used to keep track of the index
int loopIndex = 0;
foreach(var item in list)
{
    // access the item and the index
    Console.WriteLine($"ItemValue: {item}");
    Console.WriteLine($"index: {loopIndex}");

    // don't forget to increase the index
    loopIndex++;
}

With this approach, the item from the list can be accessed, as well as the index (position) of the item in the list. The output:

ItemValue: 1
index: 0
ItemValue: 2
index: 1
ItemValue: 3
index: 2
ItemValue: 4
index: 3
ItemValue: 5
index: 4

This approach is entirely valid, however it does require additional effort, and the developer needs to remember to increase the index variable. There is a cleaner, simpler approach (however, it might come with a performance cost)


Tuple index

Instead of manually creating and incrementing an index variable, this can be done automatically with the foreach loop:

// list with 5 items
var list = new List<int>();
list.AddRange(Enumerable.Range(1, 5));

// instead of iterating through the list directly
// select the items of the list into a tuple, along
// with the index
foreach(var (item, index) in 
    list.Select((item, index) => (item, index)))
{
    Console.WriteLine($"ItemValue: {item}");
    Console.WriteLine($"index: {index}");
}

Here, the items in the list are select into a list of tuples, each tuple containing the item itself, as well as the index. Iterating over this new list gives us access to both these values.

The output is the same as before:

ItemValue: 1
index: 0
ItemValue: 2
index: 1
ItemValue: 3
index: 2
ItemValue: 4
index: 3
ItemValue: 5
index: 4

Cleaner, simpler and less prone to errors (forgetting to increment the index manually)


Notes

A relatively simple tip, but one which does make things easier as a developer - however depending on the list size and the list type, could result in a performance hit. If the list is generally relatively small, the performance hit shouldn't be noticeable and the code is cleaner. But still perform benchmark and use the best solution for your use case


References

David Pine Tweet

Daily Drop 202: 15-11-2022

At the start of 2022 I set myself the goal of learning one new coding related piece of knowledge a day.
It could be anything - some.NET / C# functionality I wasn't aware of, a design practice, a cool new coding technique, or just something I find interesting. It could be something I knew at one point but had forgotten, or something completely new, which I may or may never actually use.

The Daily Drop is a record of these pieces of knowledge - writing about and summarizing them helps re-enforce the information for myself, as well as potentially helps others learn something new as well.
c# .net foreach index