Programming
Foreach Loop
Indexing
Iteration
Coding Tips

How do you get the index of the current iteration of a foreach loop?

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

A foreach loop is designed to give you values, not positions. When you also need the current index, the answer depends on the language you are using: some languages provide a built-in helper, while others expect you to switch to an indexed loop or keep a counter yourself. The most important rule is not to fight the loop construct when an indexed loop would express the job more clearly.

Why foreach Usually Hides the Index

The point of foreach is to abstract away collection mechanics. It is ideal when all you care about is the current element:

java
for (String name : names) {
    System.out.println(name);
}

This keeps the code focused on values rather than array positions. As soon as the logic also depends on the position, you are asking the loop for something it was not primarily designed to expose.

That does not mean foreach is wrong. It just means you should use the indexed pattern that is most natural in your language.

Use a Counter in Languages Like Java

Java's enhanced for loop does not expose the current index directly. The most straightforward solution is to keep a counter:

java
1int index = 0;
2for (String name : names) {
3    System.out.println(index + ": " + name);
4    index++;
5}

This is perfectly acceptable Java. It is clear, fast, and easy to maintain.

If the loop has complex control flow with continue or early exits, be careful to increment the counter in the right place. For logic that is fundamentally about positions, a classic indexed loop is often cleaner.

Prefer Built-In Indexed Helpers When the Language Has Them

Some languages give you a better option than a manual counter.

Python has enumerate:

python
1names = ["Ada", "Linus", "Grace"]
2
3for index, name in enumerate(names):
4    print(index, name)

JavaScript passes the index to forEach:

javascript
1const names = ["Ada", "Linus", "Grace"];
2
3names.forEach((name, index) => {
4  console.log(index, name);
5});

C# can project values with their indices before the foreach:

csharp
1using System;
2using System.Linq;
3
4var names = new[] { "Ada", "Linus", "Grace" };
5
6foreach (var item in names.Select((value, index) => new { value, index }))
7{
8    Console.WriteLine($"{item.index}: {item.value}");
9}

These language-specific helpers are usually better than inventing your own index lookup logic.

Sometimes a Classic Indexed Loop Is Better

If you need to modify elements by position, compare neighbors, skip ahead manually, or access multiple collections in parallel, an indexed loop is often the right tool.

Example in Java:

java
for (int i = 0; i < names.size(); i++) {
    System.out.println(i + ": " + names.get(i));
}

This is not less elegant than foreach when the index is central to the algorithm. It is simply more honest about what the code is doing.

Many developers overvalue foreach and end up wrapping it in extra bookkeeping that is harder to read than a plain indexed loop.

Avoid indexOf Inside the Loop

A tempting but flawed approach looks like this:

java
1for (String name : names) {
2    int index = names.indexOf(name);
3    System.out.println(index + ": " + name);
4}

This has two big problems:

  • it scans the collection repeatedly, which is inefficient
  • it fails with duplicate values because indexOf returns the first match

If the collection is ["a", "b", "a"], the second "a" still reports index 0, which is wrong for the current iteration.

That is why index-tracking should come from the loop structure, not from searching the collection during each iteration.

Match the Solution to the Language and Problem

The best approach depends on both the language and the task:

  • manual counter for simple languages or simple loops
  • built-in indexed iterator such as Python enumerate
  • classic indexed for loop when position is central to the logic

Trying to force every problem into a foreach shape usually makes the code less readable, not more.

Common Pitfalls

One common mistake is assuming every foreach loop has a hidden current-index variable that you can access somehow. Many languages do not expose one.

Another mistake is using indexOf inside the loop. That is both inefficient and incorrect when duplicate values exist.

Developers also sometimes keep a manual counter but forget to update it along every path through the loop. If the loop contains continue statements or branching logic, the counter can drift out of sync.

Finally, if your logic depends heavily on positions, adjacent comparisons, or random access, it is usually better to stop forcing foreach and use an indexed loop instead.

Summary

  • A foreach loop typically exposes values, not indices.
  • In Java and similar languages, keep a manual counter or use an indexed loop.
  • Prefer built-in helpers such as Python enumerate when the language provides them.
  • Do not use indexOf inside the loop to recover the current position.
  • If position is part of the algorithm, an indexed for loop is often the clearest tool.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design