Question

Comment puis-je obtenir la clé de l'élément actuel dans un foreach boucle en C# ?

Par exemple:

PHP

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

Ce que j'essaie de faire 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
    }
}
Était-ce utile?

La solution

À la manière de Grauenwolf est le moyen le plus simple et le plus performant de procéder avec un tableau :

Utilisez une boucle for ou créez une variable temporaire que vous incrémentez à chaque passage.

Ce qui ressemblerait bien sûr à ceci :

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
  }

Avec .NET 3.5, vous pouvez également adopter une approche plus fonctionnelle, mais elle est un peu plus verbeuse sur le site et s'appuierait probablement sur quelques fonctions supports pour visiter les éléments dans un IEnumerable.Exagéré si c'est tout ce dont vous avez besoin, mais pratique si vous avez tendance à effectuer beaucoup de traitements de collecte.

Autres conseils

Si vous voulez accéder à la clé (lisez :index), alors vous devrez utiliser une boucle for.Si vous souhaitez réellement disposer d'une collection contenant des clés/valeurs, j'envisagerais d'utiliser une HashTable ou un dictionnaire (si vous souhaitez utiliser des génériques).

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

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

J'espère que cela aide, Tyler

Avec DictionaryEntry et KeyValuePair :

Basé sur
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);
}

Question SO liée :KeyValuePair VS DictionaryEntry

Hélas, il n'existe aucun moyen intégré de le faire.Utilisez une boucle for ou créez une variable temporaire que vous incrémentez à chaque passage.

J'ai répondu à cela dans une autre version de cette question :

Forach est pour itération sur les collections qui mettent en œuvre ienumable.Il le fait en appelant Genenumerator sur la collection, qui renverra un énumérateur.

Cet énumérateur a une méthode et une propriété:

* MoveNext()
* Current

Le courant renvoie l'objet sur lequel Enumerator est actuellement, MOVENEXT met à jour le courant vers l'objet suivant.

De toute évidence, le concept d'un indice est étranger au concept d'énumération et ne peut pas être fait.

Pour cette raison, la plupart des collections peuvent être traversées à l'aide d'un indexeur et de la construction de boucle FOR.

Je préfère grandement utiliser une boucle pour cette situation par rapport au suivi de l'indice avec une variable locale.

Comment obtenir l'index de l'itération actuelle d'une boucle foreach ?

En fait, vous devriez utiliser la boucle classique for (;;) si vous souhaitez parcourir un tableau.Mais la fonctionnalité similaire à celle que vous avez obtenue avec votre code PHP peut être obtenue en C# comme celle-ci avec un dictionnaire :

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

Vous pouvez implémenter cette fonctionnalité vous-même à l'aide d'une méthode d'extension.Par exemple, voici une implémentation d'une méthode d'extension KeyValuePairs qui fonctionne sur les listes :

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

Voici une solution que je viens de trouver à ce problème

Code d'origine :

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

Code mis à jour

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

Méthode d'extension :

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top