¿Cómo puedo obtener 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 yo estoy tratando de 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
    }
}
InformationsquelleAutor Ross | 2008-09-12

9 Comentarios

  1. 23

    Grauenwolf del camino es el más sencillo y eficiente manera de hacer esto con una matriz:

    Utilizar un bucle for o crear una variable temporal que puede incrementar en cada paso.

    Que sería, por supuesto, este aspecto:

    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 se puede tomar un enfoque funcional, como bien, pero es un poco más detallado en el sitio, y es probable que se basan en un par de funciones de apoyo para visita los elementos en un IEnumerable. Overkill si esto es todo lo que necesita para, pero útil si usted tiende a hacer una gran cantidad de procesamiento de la recaudación.

    • «o crear una variable temporal que puede incrementar en cada paso» que yo recuerde, no hay ninguna garantía de que el bucle foreach más de su colección en un orden ascendente (o descendente) de la orden, sólo que va a parar en cada elemento en exactamente una vez, por lo tanto si usted está usando un valor externo, la solución podría o no podría ser válida basada en la aplicación. Normalmente, se le dará el resultado deseado, pero es decir, un común es la optimización para analizar una matriz en orden descendente (se tarda menos de una instrucción de máquina de orden ascendente por ciclo).
    • Yo creo que depende del tipo de enumerables que se está iterando. Si es una matriz, me gustaría pensar que podría ser garantizada.
  2. 20

    Si quieres llegar a la clave (de lectura: índice), entonces usted tendría que usar un bucle for. Si usted realmente desea tener una colección que contiene las claves/valores, a continuación, me gustaría considerar el uso de una tabla Hash o un Diccionario (si desea utilizar los 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 ayude,
    Tyler

    • Sería mucho más eficientes para hacer foreach(KeyValuePair<int, string> par de elementos) y, a continuación, la referencia de par.Clave y par.Valor, en lugar de hacer una búsqueda en cada iteración.
  3. 8

    Con DictionaryEntry y KeyValuePair:

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

    Releated ASÍ, pregunta: KeyValuePair VS DictionaryEntry

  4. 3

    Por desgracia no hay manera integrada de hacer esto. Utilizar un bucle for o crear una variable temporal que puede incrementar en cada paso.

  5. 3

    Me respondió esto en otra versión de esta pregunta:

    Foreach es para iterar sobre
    las colecciones que implementan
    IEnumerable. Esto se hace llamando a
    GetEnumerator en la colección, que
    devuelve un Enumerador.

    Este Enumerador tiene un método y un
    propiedad:

    * MoveNext()
    * Current

    Actual devuelve el objeto que
    Enumerador es que actualmente, MoveNext
    actualizaciones Actual a la siguiente objeto.

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

    Debido a que, la mayoría de las colecciones están
    capaz de ser recorrido mediante un indizador
    y para la construcción de bucle.

    Mucho me prefieren usar un bucle for en el
    esta situación en comparación con el seguimiento de
    el índice con una variable local.

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

  6. 1

    En realidad, deberían utilizar classic for (;;) de bucle si desea bucle a través de una matriz. Pero la funcionalidad similar que se han logrado con el código de PHP que se puede lograr en C# como este 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);
    }
    • Sería mucho más eficientes para hacer foreach(KeyValuePair<int a, int> par de valores) y, a continuación, la referencia de par.Clave y par.Valor, en lugar de hacer una búsqueda en cada iteración.
  7. 0

    Puede implementar esta funcionalidad usando un método de extensión. Por ejemplo, aquí es una aplicación de un método de extensión KeyValuePairs que trabaja en las 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]);
        }
    }
  8. 0

    He aquí 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;
        }
  9. -9

    myKey = Array.IndexOf(values, val);

    • Que no es una buena idea. De la matriz.IndexOf es básicamente una búsqueda con un peor caso de O(n). Hacer que n veces, puede que su total de peor caso es O(n^2). En términos sencillos, un array de 100 elementos podría tomar hasta 10000 comparaciones.
    • La eficiencia de un lado, si la matriz tiene elementos duplicados obtendrá el índice de la primera, no necesariamente el que usted está en. Considere la posibilidad de una matriz de { 5, 14, 5, 29, … }. Cuando ‘val’ es 5 siempre obtendrá cero, incluso si usted está en el tercer elemento.

Dejar respuesta

Please enter your comment!
Please enter your name here