Ich möchte Wörter in einem Wörterbuch folgendermaßen speichern:
Ich kann Wortcode für Wort erhalten: dict["SomeWord"]
-> 123
und Wort für Wortcode: dict[123]
->"SomeWord"
Ist es echt? Ein Weg, dies zu tun, sind natürlich zwei Wörterbücher: Dictionary<string,int>
und Dictionary<int,string>
aber gibt es einen anderen Weg?
c#
.net
dictionary
Neir0
quelle
quelle
Antworten:
Ich habe ein paar kurze Kurse geschrieben, in denen Sie tun können, was Sie wollen. Sie müssten es wahrscheinlich um weitere Funktionen erweitern, aber es ist ein guter Ausgangspunkt.
Die Verwendung des Codes sieht folgendermaßen aus:
Hier ist die Definition:
quelle
_forward.Add
, erfolgreich zu sein und_reverse.Add
zu scheitern, sodass Sie ein teilweise hinzugefügtes Paar haben.Forward
Dictionary-Eigenschaft selbst (die es hatprivate set;
), sondern den Wert in diesem Dictionary über die Indexer-Eigenschaft der Indexer-Klasse, die es an das Dictionary übergibt.public T4 this[T3 index] { get { return _dictionary[index]; } set { _dictionary[index] = value; } }
Das bricht also die Vorwärts- / Rückwärtssuche.Leider benötigen Sie zwei Wörterbücher, eines für jede Richtung. Mit LINQ können Sie das inverse Wörterbuch jedoch problemlos abrufen:
quelle
Erweiterung des Enigmativity-Codes durch Hinzufügen der Methode initializes und Contains.
Hier ist ein Anwendungsfall, überprüfen Sie gültige Klammern
quelle
Sie könnten zwei Wörterbücher verwenden, wie andere gesagt haben, aber beachten Sie auch, dass wenn beide
TKey
undTValue
vom gleichen Typ sind (und deren Laufzeitwertdomänen bekanntermaßen nicht zusammenhängend sind), dasselbe Wörterbuch verwenden können, indem Sie zwei Einträge für jeden Schlüssel erstellen / Wertepaarung:dict["SomeWord"]= "123"
unddict["123"]="SomeWord"
Auf diese Weise kann ein einzelnes Wörterbuch für jede Art der Suche verwendet werden.
quelle
Was zum Teufel, ich werde meine Version in die Mischung werfen:
Fügen Sie einige Daten hinzu:
Und dann machen Sie die Suche:
quelle
Sie können diese Erweiterungsmethode verwenden, obwohl sie eine Aufzählung verwendet und daher für große Datenmengen möglicherweise nicht so performant ist. Wenn Sie sich Sorgen um die Effizienz machen, benötigen Sie zwei Wörterbücher. Wenn Sie die beiden Wörterbücher in eine Klasse einschließen möchten, lesen Sie die akzeptierte Antwort auf diese Frage: Bidirektionales 1: 1-Wörterbuch in C #
quelle
Wörterbuch
Hier ist eine Mischung aus dem, was mir in jeder Antwort gefallen hat. Es wird implementiert,
IEnumerable
damit der Auflistungsinitialisierer verwendet werden kann, wie Sie im Beispiel sehen können.Nutzungsbeschränkung:
T1
≠
T2
Code:
Geige:
https://dotnetfiddle.net/mTNEuw
quelle
Bictionary<string, string>
wenn alle Saiten einzigartig sind?T1 == T2
Vorwärtssuche fehlschlägt. Außerdem kann ich den Standardindexer nicht überschreiben, da Suchaufrufe dann nicht eindeutig sind. Ich habe diese Einschränkung hinzugefügt und die vorherige entfernt, da sich die Werte vonT1
mit den Werten von überschneiden könnenT2
.try
und Ausnahmen in konvertiereKeyNotFoundExceptions
.Dies ist ein altes Problem, aber ich wollte zwei Erweiterungsmethoden hinzufügen, falls jemand es nützlich findet. Das zweite ist nicht so nützlich, bietet aber einen Ausgangspunkt, wenn eins zu eins Wörterbücher unterstützt werden müssen.
quelle
Eine modifizierte Version von Xavier Johns Antwort mit einem zusätzlichen Konstruktor zum Vorwärts- und Rückwärtsführen von Vergleichern. Dies würde beispielsweise Schlüssel unterstützen, bei denen die Groß- und Kleinschreibung nicht berücksichtigt wird. Bei Bedarf können weitere Konstruktoren hinzugefügt werden, um weitere Argumente an die Forward- und Reverse-Dictionary-Konstruktoren zu übergeben.
Anwendungsbeispiel mit einem Schlüssel ohne Berücksichtigung der Groß- und Kleinschreibung:
quelle
Hier ist mein Code. Bis auf die gesetzten Konstruktoren ist alles O (1).
quelle
Die folgende Kapselungsklasse verwendet linq (IEnumerable Extensions) über 1 Wörterbuchinstanz.
quelle
Dies verwendet einen Indexer für die umgekehrte Suche.
Die umgekehrte Suche ist O (n), es werden jedoch auch keine zwei Wörterbücher verwendet
quelle
this[string Word]
. Zusätzliche Probleme sind Variablennamen, die nicht den gängigen Praktiken entsprechen, Kommentare, die nicht mit dem Code übereinstimmen (UInt16
vsUInt32
- deshalb: Verwenden Sie keine Kommentare!), Die Lösung ist nicht generisch, ...Hier ist eine alternative Lösung zu den vorgeschlagenen. Die innere Klasse wurde entfernt und die Kohärenz beim Hinzufügen / Entfernen von Elementen sichergestellt
quelle
Da ist ein
BijectionDictionary
In diesem Open Source-Repo Typ verfügbar:https://github.com/ColmBhandal/CsharpExtras .
Es unterscheidet sich qualitativ nicht wesentlich von den anderen gegebenen Antworten. Wie die meisten dieser Antworten werden zwei Wörterbücher verwendet.
Ich glaube, was an diesem Wörterbuch im Vergleich zu den anderen bisherigen Antworten neu ist, ist, dass es sich nicht wie ein Zwei-Wege-Wörterbuch verhält, sondern nur wie ein Ein-Wege-Wörterbuch, das Ihnen vertraut ist und es Ihnen dann dynamisch ermöglicht, das Wörterbuch mithilfe von zu wechseln die Reverse-Eigenschaft. Die gespiegelte Objektreferenz ist flach, sodass weiterhin dasselbe Kernobjekt wie die ursprüngliche Referenz geändert werden kann. Sie können also zwei Verweise auf dasselbe Objekt haben, außer dass einer von ihnen umgedreht ist.
Eine andere Sache, die an diesem Wörterbuch wahrscheinlich einzigartig ist, ist, dass im Testprojekt unter diesem Repo einige Tests dafür geschrieben wurden. Es wurde von uns in der Praxis verwendet und war bisher ziemlich stabil.
quelle
Es gibt eine erweiterte Version der Antwort von Enigmativity als Nuget-Paket https://www.nuget.org/packages/BidirectionalMap/
Es ist Open Source hier
quelle