Es ist einfach, den Wert eines Schlüssels aus einem generischen .NET-Wörterbuch abzurufen:
Dictionary<int, string> greek = new Dictionary<int, string>();
greek.Add(1, "Alpha");
greek.Add(2, "Beta");
string secondGreek = greek[2]; // Beta
Der Versuch, den Schlüsseln einen Wert zu geben, ist jedoch nicht so einfach, da es mehrere Schlüssel geben kann:
int[] betaKeys = greek.WhatDoIPutHere("Beta"); // expecting single 2
int[]
wenn Sie einen einzelnen Wert erwarten?Antworten:
Okay, hier ist die mehrfach bidirektionale Version:
quelle
Wie alle anderen gesagt haben, gibt es in einem Wörterbuch keine Zuordnung von Wert zu Schlüssel.
Ich habe gerade bemerkt, dass Sie eine Zuordnung von Wert zu mehreren Schlüsseln vornehmen möchten. Ich lasse diese Lösung hier für die Einzelwertversion, füge dann aber eine weitere Antwort für eine bidirektionale Zuordnung mit mehreren Einträgen hinzu.
Der normale Ansatz besteht darin, zwei Wörterbücher zu haben - eines in eine Richtung und eines in die andere. Kapseln Sie sie in eine separate Klasse und überlegen Sie, was Sie tun möchten, wenn Sie einen doppelten Schlüssel oder Wert haben (z. B. eine Ausnahme auslösen, den vorhandenen Eintrag überschreiben oder den neuen Eintrag ignorieren). Persönlich würde ich wahrscheinlich eine Ausnahme auslösen - dies erleichtert die Definition des Erfolgsverhaltens. Etwas wie das:
quelle
Add
fehl - aber wenn es der zweite ist, haben wir das System in einen verwirrten Zustand versetzt. Meiner Meinung nach haben Sie nach der Ausnahme immer noch eine konsistente Sammlung.Wörterbücher sollen eigentlich nicht so funktionieren, denn die Eindeutigkeit von Schlüsseln ist zwar garantiert, die Eindeutigkeit von Werten jedoch nicht. Also zB wenn du es hättest
Was würden Sie erwarten, um zu bekommen
greek.WhatDoIPutHere("Alpha")
?Daher können Sie nicht erwarten, dass so etwas in das Framework integriert wird. Sie benötigen eine eigene Methode für Ihre eigenen Zwecke - möchten Sie ein Array (oder
IEnumerable<T>
) zurückgeben? Möchten Sie eine Ausnahme auslösen, wenn der angegebene Wert mehrere Schlüssel enthält? Was ist, wenn es keine gibt?Persönlich würde ich mich für eine Aufzählung entscheiden, wie folgt:
quelle
Der vielleicht einfachste Weg, dies ohne Linq zu tun, besteht darin, die Paare zu durchlaufen:
Wenn Sie Linq hätten, hätte es leicht so gehen können:
quelle
var
ist eine Sprachfunktion, keine Framework-Funktion. Sie können Null-Coalescing von C # -6.0 verwenden und trotzdem auf CF-2.0 abzielen, wenn Sie dies wirklich möchten.Ein Wörterbuch enthält keinen Hash der Werte, sondern nur der Schlüssel. Daher dauert jede Suche mit einem Wert mindestens linear. Am besten iterieren Sie einfach über die Elemente im Wörterbuch und verfolgen die übereinstimmenden Schlüssel oder wechseln zu einer anderen Datenstruktur. Behalten Sie möglicherweise zwei Wörterbuchzuordnungsschlüssel bei -> Wert und Wert-> List_of_keys. Wenn Sie Letzteres tun, tauschen Sie Speicher gegen Suchgeschwindigkeit. Es würde nicht viel kosten, das @ Cybis-Beispiel in eine solche Datenstruktur umzuwandeln.
quelle
Da ich ein vollwertiges biDirektionales Wörterbuch (und nicht nur eine Karte) haben wollte, habe ich die fehlenden Funktionen hinzugefügt, um es zu einer IDictionary-kompatiblen Klasse zu machen. Dies basiert auf der Version mit eindeutigen Schlüssel-Wert-Paaren. Hier ist die Datei, falls gewünscht (die meiste Arbeit war das XMLDoc durch):
quelle
überarbeitet: Okay, um eine Art Fund zu haben, würden Sie etwas anderes als ein Wörterbuch benötigen, denn wenn Sie darüber nachdenken, sind Wörterbücher Einwegschlüssel. Das heißt, die Werte sind möglicherweise nicht eindeutig
Das heißt, es sieht so aus, als würden Sie c # 3.0 verwenden, sodass Sie möglicherweise nicht auf Schleifen zurückgreifen müssen und Folgendes verwenden könnten:
quelle
Die Wörterbuchklasse ist für diesen Fall nicht optimiert, aber wenn Sie es wirklich wollten (in C # 2.0), können Sie Folgendes tun:
Ich bevorzuge die LINQ-Lösung für Eleganz, aber dies ist der 2.0-Weg.
quelle
Können Sie keine Unterklasse von Dictionary erstellen, die diese Funktionalität hat?
EDIT: Sorry, habe den Code beim ersten Mal nicht richtig verstanden.
quelle
Die hier vorgeschlagene "einfache" bidirektionale Wörterbuchlösung ist komplex und möglicherweise schwer zu verstehen, zu warten oder zu erweitern. Auch die ursprüngliche Frage fragte nach "dem Schlüssel für einen Wert", aber es könnte eindeutig mehrere Schlüssel geben (ich habe die Frage seitdem bearbeitet). Der ganze Ansatz ist ziemlich verdächtig.
Softwareänderungen. Das Schreiben von Code, der einfach zu warten ist, sollte Vorrang vor anderen "cleveren" komplexen Problemumgehungen haben. Der Weg, um Schlüssel von Werten in einem Wörterbuch zurückzubekommen, ist eine Schleife. Ein Wörterbuch ist nicht bidirektional ausgelegt.
quelle
int
Werte prostring
Schlüssel unterstützt, kann das Wörterbuch folgendermaßen definiert werden :Dictionary<string, List<int>>
.Dictionary
ist nicht eine bidirektionale Fähigkeit bieten. Wenn Sie also nur einen Standard habenDictionary
und die Schlüssel finden möchten, die einem bestimmten Wert zugeordnet sind, müssen Sie tatsächlich iterieren! Bei "großen" Wörterbüchern kann das Iterieren jedoch zu einer schlechten Leistung führen. Beachten Sie, dass die Antwort , die ich selbst angeboten habe, auf Iteration basiert (über LINQ). Wenn sich Ihre InitialeDictionary
nicht weiter ändert, können SieDictionary
einmal eine Umkehrung erstellen, um die Rückwärtssuche zu beschleunigen.Verwenden Sie LINQ , um eine umgekehrte
Dictionary<K, V>
Suche durchzuführen. Beachten Sie jedoch, dass die Werte in IhrenDictionary<K, V>
Werten möglicherweise nicht unterschiedlich sind.Demonstration:
Erwartete Ausgabe:
quelle
quelle
Als eine Wendung der akzeptierten Antwort ( https://stackoverflow.com/a/255638/986160 ) unter der Annahme, dass die Schlüssel mit Signle-Werten im Wörterbuch verknüpft werden. Ähnlich wie ( https://stackoverflow.com/a/255630/986160 ), aber etwas eleganter. Die Neuheit besteht darin, dass die konsumierende Klasse als Aufzählungsalternative verwendet werden kann (aber auch für Zeichenfolgen) und dass das Wörterbuch IEnumerable implementiert.
Und als konsumierende Klasse könnten Sie haben
quelle
Dann die Lösung für Laien
Eine ähnliche Funktion wie die folgende könnte geschrieben werden, um ein solches Wörterbuch zu erstellen:
quelle