Domanda

Come ottengo la chiave dell'elemento corrente in a foreach ciclo in C#?

Per esempio:

PHP

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

Quello che sto cercando di fare in C#:

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

foreach (int val in values)
{
    if(search <= val && !stop)
    {
         // Set key to a variable
    }
}
È stato utile?

Soluzione

Alla maniera di Grauenwolf è il modo più semplice ed efficace per farlo con un array:

Utilizza un ciclo for o crea una variabile temporanea da incrementare ad ogni passaggio.

Che ovviamente sarebbe simile a questo:

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 puoi anche adottare un approccio più funzionale, ma è un po' più dettagliato sul sito e probabilmente farebbe affidamento su un paio funzioni di supporto per visitare gli elementi in un IEnumerable.Eccessivo se questo è tutto ciò di cui hai bisogno, ma utile se tendi a eseguire molte elaborazioni di raccolta.

Altri suggerimenti

Se vuoi ottenere la chiave (leggi:index) allora dovresti usare un ciclo for.Se desideri effettivamente avere una raccolta che contenga chiavi/valori, prenderei in considerazione l'utilizzo di una HashTable o di un dizionario (se desideri utilizzare Generics).

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

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

Spero che questo aiuti, Tyler

Con DictionaryEntry e KeyValuePair:

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

Domanda SO correlata:KeyValuePair VS DictionaryEntry

Purtroppo non esiste un modo integrato per farlo.Utilizza un ciclo for o crea una variabile temporanea da incrementare ad ogni passaggio.

Ho risposto a questo in un'altra versione di questa domanda:

Foreach sta per ripetere le collezioni che implementano Ienumerable.Lo fa chiamando getEnumerator sulla collezione, che restituirà un enumeratore.

Questo enumeratore ha un metodo e una proprietà:

* MoveNext()
* Current

Corrente restituisce l'oggetto che l'enumeratore è attualmente acceso, MovEnext aggiorna la corrente all'oggetto successivo.

Ovviamente, il concetto di indice è estraneo al concetto di enumerazione e non può essere fatto.

Per questo motivo, la maggior parte delle collezioni è in grado di essere attraversate usando un indicizzatore e il costrutto per loop.

Preferisco molto usare un ciclo per in questa situazione rispetto al monitoraggio dell'indice con una variabile locale.

Come si ottiene l'indice dell'iterazione corrente di un ciclo foreach?

In realtà dovresti usare il classico ciclo for (;;) se vuoi scorrere un array.Ma la funzionalità simile che hai ottenuto con il tuo codice PHP può essere ottenuta in C# in questo modo con un dizionario:

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

Puoi implementare questa funzionalità tu stesso utilizzando un metodo di estensione.Ad esempio, ecco un'implementazione di un metodo di estensione KeyValuePairs che funziona sugli elenchi:

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

Ecco una soluzione che ho appena trovato per questo problema

Codice originale:

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

Codice aggiornato

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

Metodo di estensione:

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top