2015-01-03 10 views
6

Czy klasa mapy w Dart ma sposób zignorowania przypadku, jeśli klucz jest ciągiem?Mapa darta z kluczem String, porównaj z przypadkiem ignorowania

Np.

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

W języku C# konstruktor słownika przyjmuje porównywarkę, jak powyższy komentarz. Jaki jest kanoniczny sposób na zrobienie tego w Dart?

Odpowiedz

4

Mapy w Dart mieć metodę wewnętrznego, który porównuje kluczy dla równości. O ile wiem, nie można tego zmienić dla domyślnej klasy Map. Można jednak użyć bardzo podobnej klasy rdzeniowej LinkedHashMap, która nie tylko pozwala, ale wymaga określenia metody równości klucza. Możesz sprawdzić się więcej o LinkedHashMaps na https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/dart:collection.LinkedHashMap

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

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

Jeśli zrobisz nową Mapę (), faktycznie otrzymasz LinkedHashMap. Można to zobaczyć w fabrycznym kontrruktorze Map (fabrycznie Map() = LinkedHashMap ;) –

+0

Istnieje funkcja w kołczanie, która ma wartość równą ignorowaniu przypadku. Obecna implementacja czyni je małymi literami, ale lepiej użyć tego niż dostarczać własne. Kod staje się następujący: Pakiet 'import ': quiver/strings.dart';' 'new LinkedHashMap > (jest równy: equalsIgnoreCase, hashCode: (String k) => k.toLowerCase(). HashCode) ; ' –

0

Możesz użyć Dictionary.
Ale to nie jest kanoniczny sposób na zrobienie tego w Dart.

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; 
    } 
} 

Wyjście

42 
4

drogę do stworzenia HashMap z funkcją zwyczaj równa (i odpowiadający niestandardową funkcję hashCode) jest użycie opcjonalnych parametrów na konstruktora HashMap:

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

Naprawdę, naprawdę polecam znaleźć sposób, aby nie zrobić toUpperCase na każdej operacji!

+0

Jest to również poprawna odpowiedź, ale LinkedHashMap jest domyślną implementacją dla mapy. Znaleźć dokumenty dla HashMap tutaj https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/dart:collection.HashMap –

0

Możesz to również zrobić, używając klasy package:collection 'CanonicalizedMap. Ta klasa jest wyraźnie zaprojektowana do obsługi map z "kanonicznymi" wersjami kluczy i jest nieco bardziej wydajna niż przekazywanie niestandardowej metody równości i kodu haskiego do zwykłego Map.