Groß- und Kleinschreibung wird nicht berücksichtigt. Der Schlüsselschlüssel wird in C # eingegeben.

154

Wenn ich eine habe, Dictionary<String,...>ist es möglich, Methoden wie ContainsKeyGroß- und Kleinschreibung nicht zu berücksichtigen?

Dies schien verwandt zu sein, aber ich habe es nicht richtig verstanden: c # Dictionary: Den Schlüssel durch Deklarationen unabhängig von Groß- und Kleinschreibung machen

Mr. Boy
quelle
5
Was ist falsch an der Verwendung StringComparer.InvariantCultureIgnoreCase? Es macht was es sagt ...
Leppie
5
Ich hatte noch nie davon gehört, daher die Frage!
Mr. Boy
2
Mögliches Duplikat des Zugriffs ohne
Berücksichtigung
Diese Frage ist verwandt, aber kein Duplikat dieser Frage. Dieser befasst sich mit dem Umgang mit einem vorhandenen Wörterbuch. Ich beginne mit neuem Code, daher sind die Antworten hier besser geeignet.
Goodeye

Antworten:

320

Dies schien verwandt zu sein, aber ich habe es nicht richtig verstanden: c # Dictionary: Den Schlüssel durch Deklarationen unabhängig von Groß- und Kleinschreibung machen

Es ist in der Tat verwandt. Die Lösung besteht darin, die Wörterbuchinstanz anzuweisen, nicht die Standardmethode zum Vergleichen von Zeichenfolgen zu verwenden (bei der zwischen Groß- und Kleinschreibung unterschieden wird), sondern eine Methode, bei der die Groß- und Kleinschreibung nicht berücksichtigt wird. Dies erfolgt mit dem entsprechenden Konstruktor :

var dict = new Dictionary<string, YourClass>(
        StringComparer.InvariantCultureIgnoreCase);

Der Konstruktor erwartet eine, IEqualityComparerdie dem Wörterbuch mitteilt, wie Schlüssel verglichen werden sollen.

StringComparer.InvariantCultureIgnoreCasegibt Ihnen eine IEqualityComparerInstanz, die Zeichenfolgen ohne Berücksichtigung der Groß- und Kleinschreibung vergleicht.

Konrad Rudolph
quelle
1
Perfekt, ich hatte irgendwie die STL-ähnliche Art verpasst, den Komparator in den CTOR zu überführen.
Mr. Boy
7
Es überrascht mich immer wieder, wie ich hier immer die Antwort auf eine Codierungsfrage finde! Vielleicht benenne ich meine nächste Katze nach dir, Konrad! :-)
Jamie
10
Möglicherweise ist der StringComparison.OrdinalIgnoreCase-Vergleich schneller als kulturbasiert
Manushin Igor
Wie mache ich das, wenn ich kein Wörterbuch erstelle, sondern versuche, ContainsKey () für eine Schlüsselübereinstimmung ohne Berücksichtigung der Groß- und Kleinschreibung für ein vorhandenes Wörterbuch zu verwenden, das ich als Teil eines Objekts erhalte?
Shridhar R Kulkarni
1
@ShridharRKulkarni Sie können grundsätzlich nicht (effizient). Die Vergleichslogik ist ein zentraler Bestandteil der internen Wörterbuchdatenstruktur. Um dies zu ermöglichen, müsste der Container mehrere Indizes für seine Daten verwalten, und Wörterbücher tun dies nicht.
Konrad Rudolph
21
var myDic = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
myDic.Add("HeLlo", "hi");

if (myDic.ContainsKey("hello"))
    Console.WriteLine(myDic["hello"]);
Steve
quelle
1
Code-Snippet sagt alles. Sehr hilfreich. Ich bin mir nicht sicher, warum dieser Beitrag im Vergleich zur akzeptierten Antwort so wenig positive Stimmen hat, nur weil ich 3 Minuten zu spät komme.
RBT
14

Es gibt nur wenige Möglichkeiten, wo Sie sich mit Wörterbüchern befassen, die von Drittanbietern oder externen DLLs abgerufen werden. Mit linq

YourDictionary.Any(i => i.KeyName.ToLower().Contains("yourstring")))

Kurkula
quelle
3
Das funktioniert super. Ein Wort der Vorsicht, wenn Sie zu wechseln Any, werden SingleOrDefaultSie nicht nullzurückkommen, wenn es nicht existiert. Stattdessen erhalten Sie ein Schlüsselwertpaar, bei dem sowohl Schlüssel als auch Wert auf gesetzt sind null!
NibblyPig
1
ContainsScheint ein sehr spezifischer Anwendungsfall für etwas zu sein, an dem Sie zu der Zeit gearbeitet haben. Als allgemeinere hilfreiche Antwort halte ich es für Equalsbesser. In diesem Sinne ist ToLower()es sogar noch besser, eine Zeichenfolge mit zu duplizieren StringComparison.xxxCase.
Suamere
1
Dies war sehr nützlich und das Entfernen des ToLower ist definitiv eine Verbesserung - mein Anwendungsfall war: return AppliedBuffs.Any (b => b.Key.Equals (Name, StringComparison.OrdinalIgnoreCase)); Ein perfektes Wörterbuch ohne Berücksichtigung der Groß- und Kleinschreibung.
David Burford
Ich bin so versucht, dies abzulehnen. Achtung, wenn Sie der Besitzer des Wörterbuchs sind, ist dies mit Sicherheit nicht der richtige Weg. Verwenden Sie diesen Ansatz nur, wenn Sie nicht wissen, wie das Wörterbuch instanziiert wurde. Verwenden Sie für eine genaue Übereinstimmung der Zeichenfolge (nicht nur dict.Keys.Contains("bla", appropriate comparer)für die Teilübereinstimmung ) die LINQ-Überladung , um die Verwendung zu vereinfachen.
Nawfal
1

Ich hatte gerade die gleichen Probleme, bei denen ich ein Wörterbuch ohne Berücksichtigung der Groß- und Kleinschreibung in einem ASP.NET Core-Controller benötigte.

Ich habe eine Erweiterungsmethode geschrieben, die den Trick macht. Vielleicht kann dies auch für andere hilfreich sein ...

public static IDictionary<string, TValue> ConvertToCaseInSensitive<TValue>(this IDictionary<string, TValue> dictionary)
{
    var resultDictionary = new Dictionary<string, TValue>(StringComparer.InvariantCultureIgnoreCase);
    foreach (var (key, value) in dictionary)
    {
        resultDictionary.Add(key, value);
    }

    dictionary = resultDictionary;
    return dictionary;
}

So verwenden Sie die Erweiterungsmethode:

myDictionary.ConvertToCaseInSensitive();

Dann holen Sie sich einen Wert aus dem Wörterbuch mit:

myDictionary.ContainsKey("TheKeyWhichIsNotCaseSensitiveAnymore!");
Fähre Jongmans
quelle
0

Wenn Sie bei der Instanzerstellung keine Kontrolle haben, beispielsweise wenn Ihr Objekt von JSON usw. desterilisiert ist, können Sie eine Wrapper-Klasse erstellen, die von der Dictionary-Klasse erbt.

public class CaseInSensitiveDictionary<TValue> : Dictionary<string, TValue>
{
    public CaseInSensitiveDictionary() : base(StringComparer.OrdinalIgnoreCase){}
}
AG
quelle