Frage

Nehmen wir an, ich habe ein Wörterbuchobjekt:

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

Jetzt möchte ich in umgekehrter Reihenfolge durch das Wörterbuch iterieren. Ich kann keine einfache Schleife verwenden, weil ich die Schlüssel des Wörterbuchs nicht kenne. EIN für jeden ist einfach:

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

Aber wie kann ich das umgekehrt ausführen?

War es hilfreich?

Lösung

Ich würde eine sortierte Liste anstelle eines Wörterbuchs verwenden. Sie können immer noch per Key darauf zugreifen, aber Sie können auch mit Index darauf zugreifen.

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

Es ist erwähnenswert, dass in einer sortierten Liste Schlüssel-/Wertpaare nur nach Schlüssel sortiert werden.

Andere Tipps

Ein Wörterbuch oder eine andere Form von Hashtable hat keine Bestellung. Also, was Sie versuchen zu tun, ist sinnlos :)

Wenn Sie .NET 3.5 haben, können Sie die .Reverse () -Erweiterungsmethode für iEnumerable verwenden. Zum Beispiel:

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

Tatsächlich können Sie in C# 2.0 Ihren eigenen Iterator erstellen, der einen Container umgekehrt durchquert. Dann können Sie diesen Iterator in Ihrer Foreach -Erklärung verwenden. Aber Ihr Iterator müsste in erster Linie einen Weg haben, durch den Container zu navigieren. Wenn es sich um ein einfaches Array handelt, könnte es so rückwärts gehen:

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

Aber natürlich können Sie das mit einem Wörterbuch nicht tun, da es ILIST nicht implementiert oder einen Indexer bietet. Zu sagen, dass ein Wörterbuch keine Ordnung hat, ist nicht wahr: Natürlich hat es Ordnung. Diese Reihenfolge kann sogar nützlich sein, wenn Sie wissen, was sie ist.

Für eine Lösung für Ihr Problem: Ich würde sagen, die Elemente in ein Array kopieren und die obige Methode verwenden, um sie umgekehrt zu durchqueren. So was:

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

}

Das Kopieren Ihrer Werte in ein Array mag eine schlechte Idee erscheinen, aber abhängig von der Art des Wertes ist es nicht wirklich so schlimm. Sie könnten nur Referenzen kopieren!

Ich stimme @leppie zu, denke aber, dass Sie eine Antwort auf die Frage im Allgemeinen verdienen. Es könnte sein, dass Sie für die Frage im Allgemeinen gedacht haben, aber versehentlich eine schlechte Datenstruktur ausgewählt haben. Die Reihenfolge der Werte in einem Wörterbuch sollte als implementierungsspezifisch angesehen werden. Nach der Dokumentation ist es immer die gleiche Reihenfolge wie die Schlüssel, aber diese Reihenfolge ist auch nicht spezifiziert.

Wie auch immer, es gibt keinen einfachen Weg zu machen foreach umgekehrt arbeiten. Es handelt sich um syntaktische Zucker, um den Aufzähler der Klasse zu verwenden, und Enumeratoren können nur in eine Richtung reisen. Technisch gesehen könnte die Antwort "die Sammlung umkehren und dann aufzählen", aber ich denke, dies ist ein Fall, in dem Sie nur eine "Rückwärts" für Loop verwenden müssen:

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

Wenn Sie nicht .NET 3.5 und daher die Reverse -Erweiterungsmethode haben, können Sie Ihre eigenen implementieren. Ich würde vermuten, dass es wahrscheinlich eine Zwischenliste erzeugt (wenn nötig) und sie umgekehrt iteriert, so etwas wie folgt:

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

Das wäre ein Dictionary<int, SomeObject> myDictionary, und du würdest es tun von:

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

Der einzige Weg, den ich mir einfallen lassen kann .NET 2.0 soll zuerst alle Werte in eine Liste kopieren, die Liste umkehren und dann die Foreach in dieser Liste ausführen:

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
}

Wenn die Bestellung am wichtigsten ist, könnten Sie einen Stapel und eine einfache Struktur erstellen, um Ihr INT -Objektpaar zu speichern.

Wenn Sie eine Wörterbuch -Sammlung wünschen, die Einfügungsreihenfolge beibehalten müssen, können Sie die KeyedCollection untersuchenhier

Es ist eine Fusion zwischen einem Wörterbuch und einer Liste. Auf diese Weise können Sie über den Schlüssel oder den Insertionsindex auf Elemente in der Sammlung zugreifen.

Das einzige Gotcha ist, wenn Ihr Element, das in der Sammlung gespeichert wird, einen INT -Schlüssel haben muss. Wenn Sie dies in eine Zeichenfolge oder einen anderen Typ ändern könnten (GUID mabye). Seit Sammlung1 sucht nach dem Schlüssel von 1 und nicht nach dem Index von 1.

Ein Standard for Loop wäre am besten. Sie müssen sich keine Sorgen um den Verarbeitungsaufwand der Umkehrung der Sammlung machen.

Du kannst den ... benutzen Linq zu Objekten Aufzählbar.Reverse () Funktion in .net 2.0 verwendet Linqbridge.

Wörtliche Antwort:

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;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top