Pregunta

¿Cómo obtengo la clave del elemento actual en un foreach bucle en C#?

Por ejemplo:

PHP

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

Lo que estoy intentando hacer en C#:

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

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

Solución

El camino de Grauenwolf es la forma más sencilla y eficaz de hacer esto con una matriz:

Utilice un bucle for o cree una variable temporal que incremente en cada pasada.

Que por supuesto se vería así:

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
  }

Con .NET 3.5 también puedes adoptar un enfoque más funcional, pero es un poco más detallado en el sitio y probablemente dependa de un par de funciones de apoyo para visitando los elementos en un IEnumerable.Excesivo si esto es todo lo que lo necesita, pero útil si tiende a realizar mucho procesamiento de colecciones.

Otros consejos

Si desea obtener la clave (lea:index) entonces tendrías que usar un bucle for.Si realmente desea tener una colección que contenga claves/valores, entonces consideraría usar una HashTable o un Diccionario (si desea 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 eso ayude, Tyler

Con DictionaryEntry y KeyValuePair:

Residencia en
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);
}

Pregunta SO relacionada:KeyValuePair VS Entrada de diccionario

Lamentablemente, no existe una forma integrada de hacer esto.Utilice un bucle for o cree una variable temporal que incremente en cada pasada.

Respondí esto en otra versión de esta pregunta:

Foreach es para iterar sobre colecciones que implementan IEnumerables.Lo hace llamando a Getenumerator en la colección, que devolverá un enumerador.

Este enumerador tiene un método y una propiedad:

* MoveNext()
* Current

Current Devuelve el objeto en el que se encuentra Enumerator, MoveNext se actualiza actual al siguiente objeto.

Obviamente, el concepto de un índice es extraño al concepto de enumeración y no se puede hacer.

Debido a eso, la mayoría de las colecciones pueden atravesar utilizando un indexador y la construcción de bucle for.

Prefiero usar un bucle para un bucle para esta situación en comparación con el seguimiento del índice con una variable local.

¿Cómo se obtiene el índice de la iteración actual de un bucle foreach?

En realidad, deberías usar el bucle for (;;) clásico si quieres recorrer una matriz.Pero la funcionalidad similar que has logrado con tu código PHP se puede lograr en C# así con un Diccionario:

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);
}

Puede implementar esta funcionalidad usted mismo utilizando un método de extensión.Por ejemplo, aquí hay una implementación de un método de extensión KeyValuePairs que funciona en 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]);
    }
}

Aquí hay una solución que se me ocurrió 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 actualizado

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

Método de extensión:

    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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top