Ich benutze ein Dictionary<string, int>
wo das int
eine Zählung des Schlüssels ist.
Jetzt muss ich auf den zuletzt eingefügten Schlüssel im Wörterbuch zugreifen, aber ich kenne den Namen nicht. Der offensichtliche Versuch:
int LastCount = mydict[mydict.keys[mydict.keys.Count]];
funktioniert nicht, da Dictionary.Keys
kein [] -Indexer implementiert ist.
Ich frage mich nur, ob es eine ähnliche Klasse gibt. Ich habe über die Verwendung eines Stacks nachgedacht, aber darin wird nur eine Zeichenfolge gespeichert. Ich könnte jetzt meine eigene Struktur erstellen und dann eine verwenden Stack<MyStruct>
, aber ich frage mich, ob es eine andere Alternative gibt, im Wesentlichen ein Wörterbuch, das einen [] -Indexer auf den Schlüsseln implementiert?
c#
.net
dictionary
Michael Stum
quelle
quelle
Antworten:
Wie @Falanwe in einem Kommentar betont, ist es falsch , so etwas zu tun :
Sie sollten nicht von der Reihenfolge der Schlüssel in einem Wörterbuch abhängig sein. Wenn Sie eine Bestellung benötigen, sollten Sie ein OrderedDictionary verwenden , wie in dieser Antwort vorgeschlagen . Die anderen Antworten auf dieser Seite sind ebenfalls interessant.
quelle
HashTable
System.Collections.ICollection zu funktionieren 'enthält keine Definition für' ElementAt 'und es konnte keine Erweiterungsmethode' ElementAt 'gefunden werden, die ein erstes Argument vom Typ' System.Collections.ICollection 'akzeptiertElementAtOrDefault
Version verwenden, um mit einer außergewöhnlichen Version zu arbeiten.Dictionary<TKey,TValue>
Dokumentation angegeben , "Die Reihenfolge der Schlüssel in derDictionary<TKey, TValue>.KeyCollection
ist nicht angegeben."mydict.Count -1
Sie können ein OrderedDictionary verwenden .
quelle
Ein Wörterbuch ist eine Hash-Tabelle, Sie haben also keine Ahnung, in welcher Reihenfolge sie eingefügt werden sollen!
Wenn Sie den zuletzt eingefügten Schlüssel wissen möchten, würde ich vorschlagen, das Wörterbuch um einen LastKeyInserted-Wert zu erweitern.
Z.B:
Sie werden jedoch auf Probleme stoßen, wenn Sie dies verwenden
.Remove()
, um dies zu überwinden, müssen Sie eine geordnete Liste der eingefügten Schlüssel führen.quelle
Warum erweitern Sie nicht einfach die Wörterbuchklasse, um eine zuletzt eingefügte Eigenschaft hinzuzufügen? So etwas wie das folgende vielleicht?
quelle
Sie können dies immer tun:
Aber ich würde es nicht empfehlen. Es gibt keine Garantie dafür, dass sich der zuletzt eingefügte Schlüssel am Ende des Arrays befindet. Die Bestellung von Schlüsseln auf MSDN ist nicht spezifiziert und kann sich ändern. In meinem sehr kurzen Test scheint es in der Reihenfolge des Einfügens zu sein, aber Sie sollten besser wie ein Stapel eine ordnungsgemäße Buchhaltung aufbauen - wie Sie vorschlagen (obwohl ich nicht sehe, dass eine Struktur auf Ihrer Grundlage erforderlich ist andere Anweisungen) - oder einzelner Variablen-Cache, wenn Sie nur den neuesten Schlüssel kennen müssen.
quelle
Ich denke, Sie können so etwas tun, die Syntax könnte falsch sein, seit einiger Zeit kein C # mehr verwendet, um das letzte Element zu erhalten
oder verwenden Sie Max anstelle von Last, um den Maximalwert zu erhalten. Ich weiß nicht, welcher besser zu Ihrem Code passt.
quelle
Ich stimme dem zweiten Teil von Patricks Antwort zu. Auch wenn in einigen Tests die Einfügereihenfolge beibehalten zu werden scheint, wird in der Dokumentation (und im normalen Verhalten für Wörterbücher und Hashes) ausdrücklich angegeben, dass die Reihenfolge nicht angegeben ist.
Sie fragen nur nach Ärger, abhängig von der Reihenfolge der Schlüssel. Fügen Sie Ihre eigene Buchhaltung hinzu (wie Patrick sagte, nur eine einzige Variable für den zuletzt hinzugefügten Schlüssel), um sicherzugehen. Lassen Sie sich auch nicht von allen Methoden wie Last und Max im Wörterbuch verführen, da diese wahrscheinlich in Bezug auf den Schlüsselkomparator stehen (da bin ich mir nicht sicher).
quelle
Wenn Sie sich für die Verwendung von gefährlichem Code entscheiden, der beschädigt werden kann, ruft diese Erweiterungsfunktion einen Schlüssel von a
Dictionary<K,V>
gemäß seiner internen Indizierung ab (die für Mono und .NET derzeit in derselben Reihenfolge zu sein scheint, wie Sie sie durch Auflisten derKeys
Eigenschaft erhalten ).Es ist sehr vorzuziehen, Linq: zu verwenden
dict.Keys.ElementAt(i)
, aber diese Funktion iteriert O (N); Das Folgende ist O (1), jedoch mit einer Beeinträchtigung der Reflexionsleistung.quelle
Eine Alternative wäre eine KeyedCollection, wenn der Schlüssel in den Wert eingebettet ist.
Erstellen Sie einfach eine grundlegende Implementierung in einer versiegelten Klasse, die Sie verwenden möchten.
Also zu ersetzen
Dictionary<string, int>
(was kein sehr gutes Beispiel ist, da es keinen eindeutigen Schlüssel für ein int gibt).quelle
Die Art und Weise, wie Sie die Frage formuliert haben, lässt mich glauben, dass das int im Wörterbuch die "Position" des Elements im Wörterbuch enthält. Nach der Behauptung zu urteilen, dass die Schlüssel nicht in der Reihenfolge gespeichert sind, in der sie hinzugefügt wurden, würde dies bedeuten, dass die Schlüssel.Count (oder .Count - 1, wenn Sie nullbasiert verwenden) weiterhin vorhanden sein sollten immer die Nummer des zuletzt eingegebenen Schlüssels sein?
Wenn dies korrekt ist, gibt es einen Grund, warum Sie nicht stattdessen Dictionary <int, string> verwenden können, um mydict [mydict.Keys.Count] zu verwenden?
quelle
Ich weiß nicht, ob dies funktionieren würde, da ich ziemlich sicher bin, dass die Schlüssel nicht in der Reihenfolge gespeichert sind, in der sie hinzugefügt wurden, aber Sie könnten die KeysCollection in eine Liste umwandeln und dann den letzten Schlüssel in der Liste erhalten ... aber es wäre einen Blick wert.
Das einzige andere, woran ich denken kann, ist, die Schlüssel in einer Suchliste zu speichern und die Schlüssel zur Liste hinzuzufügen, bevor Sie sie zum Wörterbuch hinzufügen ... es ist nicht schön.
quelle
Um Daniels Beitrag und seine Kommentare zum Schlüssel zu erweitern, können Sie auf a
KeyValuePair<TKey, TValue>
als Wert zurückgreifen, da der Schlüssel ohnehin in den Wert eingebettet ist . Der Hauptgrund dafür ist, dass der Schlüssel im Allgemeinen nicht unbedingt direkt vom Wert abgeleitet werden kann.Dann würde es so aussehen:
Um dies wie im vorherigen Beispiel zu verwenden, gehen Sie wie folgt vor:
quelle
Ein Wörterbuch ist möglicherweise nicht sehr intuitiv, um den Index als Referenz zu verwenden. Sie können jedoch ähnliche Vorgänge mit einem Array von KeyValuePair ausführen :
Ex.
KeyValuePair<string, string>[] filters;
quelle
Sie können auch SortedList und sein generisches Gegenstück verwenden. Diese beiden Klassen und die in Andrew Peters Antwort erwähnte OrderedDictionary sind Wörterbuchklassen, in denen auf Elemente sowohl nach Index (Position) als auch nach Schlüssel zugegriffen werden kann. Verwendung dieser Klassen finden Sie unter: SortedList Class , SortedList Generic Class .
quelle
UserVoice von Visual Studio enthält einen Link zur generischen OrderedDictionary-Implementierung von dotmore.
Wenn Sie jedoch nur Schlüssel / Wert-Paare nach Index und keine Werte nach Schlüsseln abrufen müssen, können Sie einen einfachen Trick verwenden. Deklarieren Sie eine generische Klasse (ich habe sie ListArray genannt) wie folgt:
Sie können es auch mit Konstruktoren deklarieren:
Sie lesen beispielsweise einige Schlüssel / Wert-Paare aus einer Datei und möchten sie nur in der Reihenfolge speichern, in der sie gelesen wurden, um sie später per Index abzurufen:
Wie Sie vielleicht bemerkt haben, können Sie nicht unbedingt nur Schlüssel / Wert-Paare in Ihrem ListArray haben. Die Elementarrays können beliebig lang sein, wie in einem gezackten Array.
quelle