How to get index of the current iteration of a foreach?

3

Normally, in order to get the current iteration index within a foreach , I do this:

int i=0;
foreach (var elemento in list)
{    
   // Qualquer coisa
   i++;
}

I believe there are other methods to get the iteration index (even more "nice" than the one presented) , what are they?

    
asked by anonymous 06.09.2016 / 03:43

5 answers

5

Actually if you really need the index, the right thing is to use for .

If you do not want to use the right tool for the problem, the most obvious solution is the one presented in the question.

Otherwise the solution is to use LINQ, which I think is an exaggeration for the problem and is rarely a better solution than the previous ones in any analysis that is done - if I make a general analysis, I doubt that she is good in any situation. It would look something like this:

foreach (var pair in list.Select((x, i) => new {Index = i, Value = x})) {
    WriteLine($"{pair.Index}: {pair.Value}");
}

See working on dotNetFiddle .

I find it less legible, less performative and I can not see any gain.

Some prefer to create some abstraction on top of this, such as an extension method that hides the implementation details a bit, or a class that deals with it. In rare cases I find it appropriate. Depending on the case (where a method overrides the loop) changes the semantics and few programmers know how to handle it right. It ends up being overkill to avoid obvious and simple use.

What could make it a bit better, something like this:

foreach (var pair in list.IndexPair()) {
    WriteLine($"{pair.Index}: {pair.Value}");
}

public static class IEnumerableExt {
    public static IEnumerable<T> IndexPair(this IEnumerable<T> enumerable) {
        return enumerable.Select((x, i) => new {Index = i, Value = x});
    }
}

I've seen some solutions so strange that I refuse to post here.

    
06.09.2016 / 04:03
4

The foreach has no knowledge of the current index to expose it in an elegant way, you have to manually control a variable yourself. This is because foreach is an independent structure of a data type that needs to work with indexing by numbers. It works only on the interface IEnumerable and IEnumerator .

Not having an index in foreach makes perfect sense, since you can implement using foreach in structures that do not have indexing, such as LinkedList

    
06.09.2016 / 04:02
4

foreach is a more elegant looping way, to iterate over elements of a collection in various languages. In C # language it is used to iterate over collections that implement IEnumerable . Then it goes by calling the GetEnumerator method which returns a Enumerator . In this Enumerator we have the properties:

MoveNext() atualiza o Current com o próximo objeto

and

Current retorna o Enumerator atual

So the concept of index in foreach is not found. Instead of using a variable outside the foreach for index control, it is more reasonable in my opinion to use the for normally:

for (int i = 1; i <= 5; i++)
{
   list[i];
   Console.WriteLine(i);
}
    
06.09.2016 / 04:02
0

You use for to control iteration, and use ElementAt to get value

static void Main(string[] args)
        {
                var lista = new List<teste>() {
                    new teste("João", 12),
                    new teste("Maria", 12),
                    new teste("José", 12),
                    new teste("Carlos", 12),
                    new teste("Juliana", 12),
                };


                for (int i = 0; i < lista.Count(); i++)
                {
                    Console.WriteLine(lista.ElementAt(i).nome);
                }


                Console.ReadKey();
            }

            public class teste
            {
                public teste()
                { }
                public teste(string _nome, int _idade)
                {
                    this.nome = _nome;
                    this.idade = _idade;
                }
                public string nome;
                public int idade;
            }
    
13.04.2018 / 16:57
0

I do not know is the most effective and performative way, however following the analogy to perform the interaction on top of a list in python, we can get the index in a foreach in C # and interact using this index on top of the list as follows .

Example:

 var lista = new List<int>(){ {100}, {200}, {300}, {400}, {500}, {600}, {700},  
                              {800}, {900}, {1000} 
 };     
foreach(var index in Enumerable.Range(0, lista.Count()).ToList())
    Console.WriteLine("Index item: "+ index + " valor item na lista: " + 
                       lista[index]);       
}

In this way instead of performing the interaction through foreach on top of the list directly, a new index list is created through (Enumerable.Range) from 0 to the total size of the list, thus creating a list of indexes of 0 to the size of the list in a range of 1 by 1.

So instead of interacting directly over the desired list, the interaction is performed on top of the index list where each index will correspond to the position of the desired element in the list, so it is possible to obtain access and obtain the index of the list element in a way similar to a traditional one.

Follow the example in .NET Fiddle: link

    
08.01.2019 / 23:30