2015-01-03 10 views
6

La classe Map in Dart ha un modo di ignorare il caso se la chiave è una stringa?Dart Map con chiave String, confronta con ignore case

Es.

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

In C# il costruttore del dizionario accetta un confronto come il commento precedente. Qual è il modo canonico per farlo in Dart?

risposta

4

Maps in Dart hanno un metodo interno che confronta le chiavi per l'uguaglianza. Per quanto ne so, non è possibile modificare questo per la classe predefinita Map. Tuttavia, è possibile utilizzare la stessa classe core LinkedHashMap, che non solo consente, ma richiede di specificare un metodo di uguaglianza delle chiavi. È possibile controllare più su LinkedHashMaps a 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

Se si esegue la nuova mappa (), si ottiene effettivamente una LinkedHashMap. Questo può essere visto nel costruttore di fabbrica per Map (factory Map() = LinkedHashMap ;) –

+0

C'è una funzione in faretra che equivale ignorando il caso. L'attuale implementazione li rende solo in minuscolo, ma potrebbe essere meglio usarli piuttosto che fornirli da soli. Il codice diventa: pacchetto 'import ': quiver/strings.dart';' 'new LinkedHashMap > (equals: equalsIgnoreCase, hashCode: (String k) => k.toLowerCase(). HashCode) ; ' –

0

È possibile utilizzare Dictionary.
Ma questo non è un modo canonico per farlo in 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; 
    } 
} 

uscita

42 
4

Il modo per creare un HashMap con una funzione uguale personalizzato (e la funzione hashCode personalizzato corrispondente) è quello di utilizzare i parametri facoltativi sulla HashMap costruttore:

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

Consiglio davvero di trovare un modo per non eseguire toUpperCase su ogni operazione!

+0

Questa è anche una risposta corretta, ma LinkedHashMap è l'implementazione predefinita che si ottiene per una mappa. Ho trovato i documenti per HashMap qui https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/dart:collection.HashMap –

0

È inoltre possibile utilizzare la classe CanonicalizedMappackage:collection. Questa classe è progettata esplicitamente per supportare mappe con versioni "canoniche" di chiavi ed è leggermente più efficiente del passaggio di un metodo di uguaglianza e codice hash personalizzato a un normale Map.