Question

Disons que j'ai un objet Dictionnaire:

Dictionary myDictionary<int, SomeObject> = new Dictionary<string, SomeObject>();

Maintenant, je veux parcourir le dictionnaire en ordre inverse. Je ne peux pas utiliser une simple boucle for car je ne connais pas les clés du dictionnaire. Un foreach est facile:

foreach (SomeObject object in myDictionary.Values)
{
    // Do stuff to object
}

Mais comment puis-je effectuer cela à l'envers?

Était-ce utile?

La solution

Je voudrais utiliser un SortedList au lieu d'un dictionnaire. Vous pouvez toujours y accéder par clé, mais également par index.

SortedList sCol = new SortedList();

sCol.Add("bee", "Some extended string matching bee");
sCol.Add("ay", "value matching ay");
sCol.Add("cee", "Just a standard cee");

// Go through it backwards.
for (int i = sCol.Count - 1; i >=0 ; i--)
    Console.WriteLine("sCol[" + i.ToString() + "] = " + sCol.GetByIndex(i));

// Reference By Key
foreach (string i in sCol.Keys)
    Console.WriteLine("sCol[" + i + "] = " + sCol[i]);

// Enumerate all values
foreach (string i in sCol.Values)
    Console.WriteLine(i);

Il est à noter qu'une liste triée stocke des paires clé / valeur triées par clé uniquement.

Autres conseils

Un dictionnaire ou toute autre forme de table de hachage ne contient aucun ordre. Donc, ce que vous essayez de faire est inutile:)

Si vous disposez de .NET 3.5, vous pouvez utiliser la méthode d'extension .Reverse () sur IEnumerables. Par exemple:

foeach (SomeObject o in myDictionary.Values.Reverse())
{
     // Do stuff to object
}

En fait, en C # 2.0, vous pouvez créer votre propre itérateur qui parcourt un conteneur en sens inverse. Ensuite, vous pouvez utiliser cet itérateur dans votre déclaration foreach. Mais votre itérateur devrait avoir un moyen de naviguer dans le conteneur en premier lieu. Si c'est un tableau simple, il pourrait revenir en arrière comme ceci:

static IEnumerable<T> CreateReverseIterator<T>(IList<T> list)
{
    int count = list.Count;
    for (int i = count - 1; i >= 0; --i)
    {
        yield return list[i];
    }
}

Mais bien sûr, vous ne pouvez pas faire cela avec un dictionnaire car il n’implémente pas IList ou ne fournit pas d’indexeur. Dire qu'un dictionnaire n'a pas d'ordre n'est pas vrai: il a bien sûr un ordre. Cet ordre peut même être utile si vous savez ce que c'est.

Pour résoudre votre problème, copiez les éléments dans un tableau et utilisez la méthode ci-dessus pour le parcourir en sens inverse. Comme ceci:

static void Main(string[] args)
{
    Dictionary<int, string> dict = new Dictionary<int, string>();

    dict[1] = "value1";
    dict[2] = "value2";
    dict[3] = "value3";

    foreach (KeyValuePair<int, string> item in dict)
    {
        Console.WriteLine("Key : {0}, Value: {1}", new object[] { item.Key, item.Value });
    }

    string[] values = new string[dict.Values.Count];
    dict.Values.CopyTo(values, 0);

    foreach (string value in CreateReverseIterator(values))
    {
        Console.WriteLine("Value: {0}", value);
    }

}

Copier vos valeurs dans un tableau peut sembler une mauvaise idée, mais selon le type de valeur, ce n’est pas vraiment si mauvais. Vous venez peut-être de copier des références!

Je suis d’accord avec @leppie, mais je pense que vous méritez une réponse à la question en général. Il se peut que vous ayez voulu dire que la question soit en général, mais que vous avez choisi accidentellement une mauvaise structure de données. L'ordre des valeurs dans un dictionnaire doit être considéré comme spécifique à l'implémentation; selon la documentation, il s'agit toujours du même ordre que les clés, mais cet ordre n'est pas spécifié non plus.

Quoi qu’il en soit, il n’existe pas de solution simple pour que foreach fonctionne à l’inverse. C'est un sucre syntaxique d'utiliser l'énumérateur de la classe, et les énumérateurs ne peuvent se déplacer que dans une direction. Techniquement, la réponse pourrait être & "; Inverser la collection, puis énumérer &"; Mais je pense que c'est un cas où vous devrez simplement utiliser un & "À l'envers &"; pour la boucle:

for (int i = myCollection.Length - 1; i >= 0; i--)
{
    // do something
}

Si vous n'avez pas .NET 3.5 et donc la méthode d'extension Reverse, vous pouvez implémenter la vôtre. J'imagine que cela génère probablement une liste intermédiaire (si nécessaire) et la réitère à l'inverse, à peu près comme suit:

public static IEnumerable<T> Reverse<T>(IEnumerable<T> items)
{
    IList<T> list = items as IList<T>;
    if (list == null) list = new List<T>(items);
    for (int i = list.Count - 1; i >= 0; i-- )
    {
        yield return list[i];
    }
}

Ce serait un Dictionary<int, SomeObject> myDictionary et vous le feriez par:

foreach(SomeObject _object in myDictionary.Values.Reverse())
{
}

Dans .NET 2.0 , je ne peux que copier d'abord toutes les valeurs dans une liste, inverser la liste, puis exécuter le foreach sur cette liste:

Dictionary<int, object> d;
List<object> tmplist;
foreach (object o in d.Values) tmplist.Add(s);
tmplist.Reverse();
foreach (object o in tmplist) {
    //Do stuff
}

Si la commande est primordiale, vous pouvez créer une pile et créer une structure simple pour stocker votre paire int. / objet.

Si vous souhaitez une collection de types de dictionnaires mais que vous devez conserver l'ordre d'insertion, vous pouvez consulter KeyedCollection. ici

C’est une fusion entre un dictionnaire et une liste. De cette façon, vous pouvez accéder aux éléments de la collection via la clé ou l'index d'insertion.

Le seul casse-tête est que votre élément stocké dans la collection doit avoir une clé int. Si vous pouviez changer cela en une chaîne ou un autre type (Guid Mabye). Depuis la collection 1 recherchera la clé 1 plutôt que le indice de 1.

Une boucle for standard serait préférable. Vous n'avez pas à vous soucier de la surcharge de traitement liée à l'inversion de la collection.

Vous pouvez utiliser le LINQ & nbsp; à & nbsp; à Objets . Fonction Enumerable.Reverse () dans .NET 2.0 utilisant LinqBridge .

Réponse littérale:

Dictionary<int, SomeObject>  myDictionary = new Dictionary<int, SomeObject>();

foreach (var pair in myDictionary.OrderByDescending(i => i.Key))
{
    //Observe pair.Key
    //Do stuff to pair.Value
}
foreach (Sample in Samples)

try the following:

Int32 nEndingSample = Samples.Count - 1;

for (i = nEndingSample; i >= 0; i--)
{
     x = Samples[i].x;
     y = Samples[i].y;
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top