Frage

Ich habe einen Wörterbuch bekommt, so etwas wie

Dictionary<Foo,String> fooDict

Ich trete durch alles, was im Wörterbuch steht, z.

foreach (Foo foo in fooDict.Keys)
    MessageBox.show(fooDict[foo]);

Es tut, dass der Foos in der Reihenfolge zu dem Wörterbuch hinzugefügt wurde, so dass das erste Element hinzugefügt ist der erst foo zurückgegeben.

Wie kann ich die Mächtigkeit ändern, so dass zum Beispiel der zweit foo zurückgegeben werden die dritt foo hinzugefügt? Mit anderen Worten, ich möchte seine ändern „Index“.

War es hilfreich?

Lösung

Wenn Sie die Dokumentation auf MSDN lesen Sie sehen:

„Die Reihenfolge, in der die Gegenstände zurückgegeben werden, ist nicht definiert.“

Sie können die Reihenfolge nicht gaurantee, weil ein Wörterbuch nicht eine Liste oder ein Array. Es soll einen Wert durch den Schlüssel suchen, und jede Fähigkeit Werte iterieren ist nur eine Bequemlichkeit, aber die Reihenfolge ist nicht Verhalten sollten Sie abhängig sind.

Andere Tipps

Sie können interessiert sein in der OrderedDicationary Klasse, die in System.Collections.Specialized Namespace.

Wenn man sich die Kommentare ganz am Ende aussehen, jemand aus MSFT hat diese interessante Notiz geschrieben:

  

Dieser Typ ist eigentlich falsch benannt; es ist nicht ein ‚bestellt‘ Wörterbuch als solche, sondern vielmehr ein ‚indiziert‘ Wörterbuch. Obwohl, heute gibt es keine Generika-Version von dieser Art ist, wenn wir eine in der Zukunft hinzuzufügen, ist es wahrscheinlich, dass wir wie Typ-Name wird ‚IndexedDictionary‘.

ich denke, es trivial sein würde, von dieser Klasse ableiten und eine generische Version von OrderedDictionary machen.

Ich bin nicht vollständig in der Domäne erzogen richtig, die Frage zu beantworten, aber ich habe ein Gefühl , dass das Wörterbuch die Werte sortiert nach dem Schlüssel, um zu Führt einen schnellen Schlüsselsuche. Dies würde darauf hindeuten, dass das Wörterbuch von Schlüsselwerten nach Schlüsselvergleich sortiert ist. Dennoch, mit Blick auf Objekt Methoden, gehe ich davon aus sie Hash-Codes verwenden unterschiedliche Objekte zu vergleichen unter Berücksichtigung es keine Anforderung von der Art für Schlüssel verwendet wird. Dies ist nur eine Vermutung. Jemand mehr knowledgey sollte mit mehr Details füllen.

Warum sind Sie daran interessiert, die „Index“ eines Wörterbuchs zu manipulieren, wenn sein Zweck Index mit beliebigen Typen ist?

Ich weiß nicht, ob jemand diese nützlich finden, aber hier ist, was ich herausfinden, endete. Es scheint zu funktionieren (womit ich meine, es keine Ausnahmen wirft), aber ich bin immer noch ein weiter Weg weg von der Lage zu testen, ob es funktioniert, wie ich es tut hoffen. Ich habe vor ein ähnliches getan, though.

        public void sortSections()
    {
        //OMG THIS IS UGLY!!!
        KeyValuePair<ListViewItem, TextSection>[] sortable = textSecs.ToArray();
        IOrderedEnumerable<KeyValuePair<ListViewItem, TextSection>> sorted = sortable.OrderBy(kvp => kvp.Value.cardinality);

        foreach (KeyValuePair<ListViewItem, TextSection> kvp in sorted)
        {
            TextSection sec = kvp.Value;
            ListViewItem key = kvp.Key;

            textSecs.Remove(key);
            textSecs.Add(key, sec);
        }
    }

Die kurze Antwort ist, dass es keinen Weg sein sollte, da ein Wörterbuch „eine Sammlung von Schlüsseln und Werten darstellt.“ das bedeutet nicht, jede Art von Ordnung. Alle hacken finden Sie vielleicht außerhalb der Definition der Klasse und kann haftbar sein ändern.

Sie sollten wahrscheinlich zuerst sich fragen, ob ein Wörterbuch wirklich in dieser Situation genannt wird, oder wenn Sie sich mit der Verwendung einer Liste der KeyValuePairs bekommen kann.

Ansonsten, so etwas wie dies könnte nützlich sein:

public class IndexableDictionary<T1, T2> : Dictionary<T1, T2>
{
    private SortedDictionary<int, T1> _sortedKeys;

    public IndexableDictionary()
    {
        _sortedKeys = new SortedDictionary<int, T1>();
    }
    public new void Add(T1 key, T2 value)
    {
        _sortedKeys.Add(_sortedKeys.Count + 1, key);
        base.Add(key, value);
    }

    private IEnumerable<KeyValuePair<T1, T2>> Enumerable()
    {
        foreach (T1 key in _sortedKeys.Values)
        {
            yield return new KeyValuePair<T1, T2>(key, this[key]);
        }
    }

    public new IEnumerator<KeyValuePair<T1, T2>> GetEnumerator()
    {
        return Enumerable().GetEnumerator();
    }

    public KeyValuePair<T1, T2> this[int index]
    {
        get
        {
            return new KeyValuePair<T1, T2> (_sortedKeys[index], base[_sortedKeys[index]]);
        }
        set
        {
            _sortedKeys[index] = value.Key;
            base[value.Key] = value.Value;
        }

    }


}

Mit Client-Code suchen etwas wie folgt aus:

    static void Main(string[] args)
    {
        IndexableDictionary<string, string> fooDict = new IndexableDictionary<string, string>();

        fooDict.Add("One", "One");
        fooDict.Add("Two", "Two");
        fooDict.Add("Three", "Three");

        // Print One, Two, Three
        foreach (KeyValuePair<string, string> kvp in fooDict)
            Console.WriteLine(kvp.Value);



        KeyValuePair<string, string> temp = fooDict[1];
        fooDict[1] = fooDict[2];
        fooDict[2] = temp;


        // Print Two, One, Three
        foreach (KeyValuePair<string, string> kvp in fooDict)
            Console.WriteLine(kvp.Value);

        Console.ReadLine();
    }

UPDATE: Aus irgendeinem Grund wird es mir nicht auf meine eigene Antwort lassen kommentieren.

Wie auch immer, IndexableDictionary unterscheidet sich von OrderedDictionary, dass

  1. „Die Elemente eines OrderedDictionary sind in keiner Weise sortiert.“ So würde foreach die Aufmerksamkeit nicht auf die numerischen Indizes zahlen
  2. Es ist stark typisiert, so dass Sie verwirren nicht mit dem Gießen die Dinge aus der Dictionary structs
  3. haben um
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top