2009-05-13 1 views
17

Fragen, ob dies möglich ist.Verwendung von Hashtables/Dictionaries mit String-Schlüsseln und Case Insensitive Search

wir eine 3rd Party Bibliothek haben, die Identifikationsinformationen über Benutzer enthält ...

Die Haupt Interaktion mit der Bibliothek einen HashTable ist durch die mit einer Zeichenfolge eingegeben wird, und gibt eine Objektgraph von Informationen für diesen Schlüssel .

Das Problem ist, ist der Schlüssel offensichtlich Case Sensitive, aber was wir von dem Benutzer-Browser bekommen nicht unbedingt den Fall nicht überein ... (Wir bekommen oft den Schlüssel vollständig lowercase'd)

I‘ Ich frage mich, ob es möglich ist, einen Fall zu tun Insensitive Schlüsselsuche gegen eine Hashtabelle.

z.B.

Hashtable ht = new Hashtable(); 
ht.Add("MyKey", "Details"); 

string result = ht["MyKey"]; 
string result = ht["MYKEY"]; 
string result = ht["mykey"]; 

auf gut Glück wir ein Support-Ticket für das Unternehmen vorlegen könnte diese Funktionalität hinzufügen, gibt es andere Datenstrukturen (dh die neuen generischen Sammlungen/Wörterbücher), die diese Funktionalität

Schließlich unterstützen würde Es ist möglich, die Methode System.String GetHashCode() zu überschreiben, so dass alle case-invarianten Strings den gleichen Hash-Code zurückgeben, z. B. Ich denke, dies ist ein nicht-Geher als string eine versiegelte Klasse

Prost ist, wenn jemand irgendwelche Vorschläge

+4

als Nebenbemerkung: Wenn Sie .NET 3.5 verwenden, sollten Sie wahrscheinlich aufhören, Hashtable usw. zu verwenden - und stattdessen die generischen Sammlungen verwenden. –

+0

Re deinen Kommentar: vielleicht einfach .ToLowerInvariant() auf alle deine Schlüssel, dann. –

+0

* Kratzer Kopf * Aber die Schlüssel, die in der Hashtable sind, sind nicht ToLowered(). I.e. Ich habe eine vordefinierte Hashtabelle, die in einer DLL instanziiert/gefüllt wird. und die Schlüssel in HT sind Case-Sensitive ... Der einzige Zugriff, den ich auf die DLL habe, ist über einen Getter/Indexer, wo ich den Schlüssel übergebe, also selbst wenn ich meine Schlüssel auf der Außenseite nicht anpasste, würden sie die Schlüssel nicht übereinstimmen auf der Innenseite. –

Antwort

30

Code, um die Hash-Tabelle Vergleiche Groß- und Kleinschreibung

Für 2.0, 3.0 zu machen, 3,5

Hashtable ht = new Hashtable(StringComparer.InvariantCultureIgnoreCase); 

Sie info

ODER

auf InvariantCultureIgnoreCase gegen OrdinalIgnoreCase auf this SO Link bekommen
Hashtable ht = System.Collections.Specialized.CollectionsUtil.CreateCaseInsensitiveHashtable(); 

Weil case-insensi Eine gängige Verwendung der dynamischen Wörterbuchsammlung ist .NET Framework mit einer CollectionUtil-Klasse, die das Erstellen von Hashtable- und SortedList-Objekten unterstützt, bei denen die Groß-/Kleinschreibung nicht berücksichtigt wird. Verwenden Sie, indem Sie CreateCaseInsensitiveHashtable oder CreateCaseInsensitiveSortedList aufrufen.

Für .Net 1.0 (Ich bin nicht sicher, ob 1.0 unterstützt StringComparer)

public class InsensitiveComparer : IEqualityComparer 
{ 
    CaseInsensitiveComparer _comparer = new CaseInsensitiveComparer(); 
    public int GetHashCode(object obj) 
    { 
     return obj.ToString().ToLowerInvariant().GetHashCode(); 
    } 

    public new bool Equals(object x, object y) 
    { 
     if (_comparer.Compare(x, y) == 0) 
     { 
      return true; 
     } 

     else 
     { 
      return false; 
     } 
    } 
} 

Hashtable dehash = new Hashtable(new InsensitiveComparer()); 
+1

Die StringComparer-Klasse bietet bereits Vergleiche ohne Berücksichtigung der Groß- und Kleinschreibung - Sie müssen keine eigenen implementieren. –

+0

Danke Daniel. Ich habe meine Antwort bearbeitet. –

+0

Dies ist nur eine FYI: Ich habe herausgefunden, dass StringDictionary Schlüssel standardmäßig Groß-und Kleinschreibung nicht beachten. Aber sowohl der Schlüssel als auch der Wert müssen Zeichenfolgen sein. –

17

Mit einem Wörterbuch hat:

new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); 

aber einfacher, glaube ich StringDictionary ist Groß- und Kleinschreibung zu:

StringDictionary ht = new StringDictionary(); 
    ht.Add("MyKey", "Details"); 

    string result1 = ht["MyKey"]; 
    string result2 = ht["MYKEY"]; 
    string result3 = ht["mykey"]; 
+0

Prost Marc. Und jubelt den anderen zu, weil sie auf die Überlastungen von IEqualityOperator hingewiesen haben ... Leider habe ich keinen Zugriff auf die Interna der Bibliothek oder den Aufbau der Hashtable ... Ich habe die Implementierung nur entdeckt, indem ich Reflector benutzt habe, um darin herumzustochern . Ich denke, ich werde ein Support-Ticket mit dem Unternehmen protokollieren und fragen, ob es als "Feature" hinzugefügt werden kann –

2

Sie können einen Groß- und Kleinschreibung IEqualityComparer an die HashTable Konstruktor übergeben werden, aber Dies erfordert, dass Sie die HashTable Konstruktion in der 3rd-Party-Bibliothek beeinflussen können.

Wenn Sie die Hash-Tabelle aus Ihrem Code ausfüllen, können Sie die Schlüssel beim Einfügen normalisieren und die normalisierten Schlüssel erneut abrufen.

Wenn Sie den Inhalt der Hash-Tabelle nicht beeinflussen können, Sie aber die Struktur der Schlüssel kennen, können Sie die Benutzereingabe korrigieren, bevor Sie auf die Hash-Tabelle zugreifen.

1

Dies ist nicht eine sehr effiziente Art und Weise, aber man kann immer die Hash-Tabelle nehmen und einen String daraus machen:

+1

+1 Das ist eine nette Idee. (Aber scheitert an "FOO" und "foo" in der Hash-Tabelle.) –

+0

Nun, die Verwendung des Indexer anstelle der Add-Methode würde eine Ausnahme verhindern, und würde keine Lösung das gleiche Problem haben, wenn die ursprüngliche Hashtable mehrere hat Schlüssel, die sich nur von Fall zu Fall unterscheiden? – Rytmis