2015-01-03 9 views
6

Hat die Map-Klasse in Dart eine Möglichkeit, case zu ignorieren, wenn der Schlüssel eine Zeichenkette ist?Dart Map mit String key, vergleichen mit ignore case

Eg.

var map = new Map<String, int>(/*MyComparerThatIgnoresCase*/); 
map["MyKey"] = 42; 
var shouldBe42 = map["mykey"]; 

In C# nimmt der Dictionary-Konstruktor einen Vergleich wie der Kommentar oben. Was ist der kanonische Weg, dies in Dart zu tun?

Antwort

4

Karten in Dart verfügen über eine interne Methode, die Schlüssel für die Gleichheit vergleicht. Soweit ich weiß, können Sie dies nicht für die Standardklasse Map ändern. Sie können jedoch die sehr ähnliche Kernklasse LinkedHashMap verwenden, die nicht nur eine Schlüsselgleichheitsmethode ermöglicht, sondern auch erfordert. Sie können

LinkedHashMap<String, String> map = new LinkedHashMap(
    (a, b) => a.toLowerCase() == b.toLowerCase(), 
    (key) => key.toLowerCase().hashCode 
); 

map['Foo'] = 'bar'; 
print(map['foo']); //bar 
+0

Wenn Sie neue Karte () tun, erhalten Sie tatsächlich eine LinkedHashMap. Dies kann in der Factory-Contructor für Map (Factory Map() = LinkedHashMap ;) –

+0

Es gibt eine Funktion in Köcher, die gleich tut beim Ignorieren von Fall. Die aktuelle Implementierung macht sie nur in Kleinbuchstaben, aber es könnte besser sein, das zu verwenden als eigene. Der Code wird dann: 'import 'Paket: quiver/strings.dart';' 'neue LinkedHashMap > (entspricht: equalsIgnoreCase, hashCode: (String k) => k.toLowerCase(). HashCode) ; ' –

0

Sie können Dictionary verwenden.
Aber das ist keine kanonische Methode, dies in Dart zu tun.

import "package:queries/collections.dart"; 

void main() { 
    var dict = new Dictionary<String, int>(new IgnoreCaseComparer()); 
    dict["MyKey"] = 42; 
    var shouldBe42 = dict["mykey"]; 
    print(shouldBe42); 
} 

class IgnoreCaseComparer implements IEqualityComparer { 
    bool equals(Object a, Object b) { 
    if (a is String && b is String) { 
     return a.toLowerCase() == b.toLowerCase(); 
    } 

    return a == b; 
    } 

    int getHashCode(Object object) { 
    if (object is String) { 
     return object.toLowerCase().hashCode; 
    } 

    return object.hashCode; 
    } 
} 

Ausgabe

42 
4

Die Art und Weise bei https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/dart:collection.LinkedHashMap mehr über LinkedHashMaps Besuche ein HashMap mit einer benutzerdefinierten (und entsprechender Funktion benutzerdefinierter hashCode) gleich Funktion zu erstellen, ist die optionalen Parameter auf das HashMap Konstruktor zu verwenden:

new HashMap<String,Whatever>(equals: (a, b) => a.toUpperCase() == b.toUpperCase(), 
          hashCode: (a) => a.toUpperCase().hashCode); 

Ich empfehle wirklich, einen Weg zu finden, die toUpperCase nicht bei jeder Operation zu tun!

+0

Dies ist auch eine korrekte Antwort, aber LinkedHashMap ist die Standardimplementierung, die Sie für eine Map erhalten. Die Dokumente für HashMap finden Sie hier https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/dart:collection.HashMap –

0

Sie können dies auch mit der package:collectionCanonicalizedMap Klasse tun. Diese Klasse ist explizit dafür ausgelegt, Karten mit "kanonischen" Versionen von Schlüsseln zu unterstützen, und ist etwas effizienter als die Übergabe einer benutzerdefinierten Gleichheits- und Hashcode-Methode an eine normale Map.