Pergunta

Como obtenho a chave do elemento atual em um foreach loop em C#?

Por exemplo:

PHP

foreach ($array as $key => $value)
{
    echo("$value is assigned to key: $key");
}

O que estou tentando fazer em C#:

int[] values = { 5, 14, 29, 49, 99, 150, 999 };

foreach (int val in values)
{
    if(search <= val && !stop)
    {
         // Set key to a variable
    }
}
Foi útil?

Solução

O caminho do Grauenwolf é a maneira mais direta e eficiente de fazer isso com um array:

Use um loop for ou crie uma variável temporária que você incrementa em cada passagem.

O que obviamente ficaria assim:

int[] values = { 5, 14, 29, 49, 99, 150, 999 };

for (int key = 0; key < values.Length; ++key)
  if (search <= values[key] && !stop)
  {
    // set key to a variable
  }

Com o .NET 3.5 você também pode adotar uma abordagem mais funcional, mas é um pouco mais detalhada no site e provavelmente dependeria de alguns funções de suporte para visitando os elementos em um IEnumerable.Um exagero se isso for tudo o que você precisa, mas útil se você tende a fazer muito processamento de coleta.

Outras dicas

Se você quiser chegar à chave (leia:index), então você teria que usar um loop for.Se você realmente deseja ter uma coleção que contenha chaves/valores, considerarei usar um HashTable ou um Dicionário (se quiser usar Genéricos).

Dictionary<int, string> items = new  Dictionary<int, string>();

foreach (int key in items.Keys)
{
  Console.WriteLine("Key: {0} has value: {1}", key, items[key]);
}

Espero que ajude, Tyler

Com DictionaryEntry e KeyValuePair:

Baseado em
MSDN

IDictionary<string,string> openWith = new Dictionary<string,string>()
{
   { "txt", "notepad.exe" }
   { "bmp", "paint.exe" }
   { "rtf", "wordpad.exe" }
};

foreach (DictionaryEntry de in openWith)
{
    Console.WriteLine("Key = {0}, Value = {1}", de.Key, de.Value);
}

// also

foreach (KeyValuePair<string,string> de in openWith)
{
    Console.WriteLine("Key = {0}, Value = {1}", de.Key, de.Value);
}

Pergunta SO divulgada:KeyValuePair VS DictionaryEntry

Infelizmente, não existe uma maneira integrada de fazer isso.Use um loop for ou crie uma variável temporária que você incrementa em cada passagem.

Eu respondi isso em outra versão desta pergunta:

Foreach é para iterar as coleções que implementam Ienumerable.Faz isso chamando o Getenumerator na coleção, que retornará um enumerador.

Este enumerador tem um método e uma propriedade:

* MoveNext()
* Current

Atualmente, retorna o objeto em que o enumerador está atualmente, o MoveNexext atualiza o atual para o próximo objeto.

Obviamente, o conceito de índice é estranho ao conceito de enumeração e não pode ser feito.

Por esse motivo, a maioria das coleções pode ser atravessada usando um indexador e o construto for loop.

Eu prefiro muito usar um loop para essa situação em comparação com o rastreamento do índice com uma variável local.

Como você obtém o índice da iteração atual de um loop foreach?

Na verdade, você deve usar o loop for (;;) clássico se quiser percorrer um array.Mas a funcionalidade semelhante que você obteve com seu código PHP pode ser alcançada em C# assim com um Dicionário:

Dictionary<int, int> values = new Dictionary<int, int>();
values[0] = 5;
values[1] = 14;
values[2] = 29;
values[3] = 49;
// whatever...

foreach (int key in values.Keys)
{
    Console.WriteLine("{0} is assigned to key: {1}", values[key], key);
}

Você mesmo pode implementar essa funcionalidade usando um método de extensão.Por exemplo, aqui está uma implementação de um método de extensão KeyValuePairs que funciona em listas:

public struct IndexValue<T> {
    public int Index {get; private set;}
    public T Value {get; private set;}
    public IndexValue(int index, T value) : this() {
        this.Index = index;
        this.Value = value;
    }
}

public static class EnumExtension
{
    public static IEnumerable<IndexValue<T>> KeyValuePairs<T>(this IList<T> list) {
        for (int i = 0; i < list.Count; i++)
            yield return new IndexValue<T>(i, list[i]);
    }
}

Aqui está uma solução que acabei de encontrar para este problema

Código original:

int index=0;
foreach (var item in enumerable)
{
    blah(item, index); // some code that depends on the index
    index++;
}

Código atualizado

enumerable.ForEach((item, index) => blah(item, index));

Método de extensão:

    public static IEnumerable<T> ForEach<T>(this IEnumerable<T> enumerable, Action<T, int> action)
    {
        var unit = new Unit(); // unit is a new type from the reactive framework (http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx) to represent a void, since in C# you can't return a void
        enumerable.Select((item, i) => 
            {
                action(item, i);
                return unit;
            }).ToList();

        return pSource;
    }

myKey = Array.IndexOf(values, val);

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top