Tengo una aplicación que usa dlls administrados. Uno de esos dlls devuelve un diccionario genérico:
Dictionary<string, int> MyDictionary;
El diccionario contiene claves con mayúsculas y minúsculas.
Por otro lado, obtengo una lista de posibles claves (cadenas), sin embargo, no puedo garantizar el caso. Estoy tratando de obtener el valor en el diccionario usando las teclas. Pero, por supuesto, lo siguiente fallará ya que tengo un caso que no coincide:
bool Success = MyDictionary.TryGetValue( MyIndex, out TheValue );
Esperaba que TryGetValue tuviera un indicador de caso de ignorar como se menciona en el documento de MSDN , pero parece que esto no es válido para diccionarios genéricos.
¿Hay alguna manera de obtener el valor de ese diccionario ignorando el caso clave? ¿Existe una solución alternativa mejor que crear una nueva copia del diccionario con el parámetro StringComparer.OrdinalIgnoreCase adecuado ?
fuente
Respuestas:
No hay forma de especificar un
StringComparer
en el punto donde intenta obtener un valor. Si lo piensa,"foo".GetHashCode()
y"FOO".GetHashCode()
es totalmente diferente, por lo que no hay una forma razonable de implementar un get que no distinga entre mayúsculas y minúsculas en un mapa hash sensible a mayúsculas y minúsculas.Sin embargo, puede crear un diccionario que no distinga entre mayúsculas y minúsculas en primer lugar usando:
O cree un nuevo diccionario que no distinga mayúsculas de minúsculas con el contenido de un diccionario existente que distinga mayúsculas de minúsculas (si está seguro de que no hay colisiones de mayúsculas y minúsculas):
Este nuevo diccionario luego usa la
GetHashCode()
implementación enStringComparer.OrdinalIgnoreCase
socomparer.GetHashCode("foo")
y lecomparer.GetHashcode("FOO")
da el mismo valor.Alternativamente, si solo hay unos pocos elementos en el diccionario, y / o solo necesita buscar una o dos veces, puede tratar el diccionario original como un
IEnumerable<KeyValuePair<TKey, TValue>>
y simplemente iterar sobre él: -O si lo prefiere, sin el LINQ: -
Esto le ahorra el costo de crear una nueva estructura de datos, pero a cambio el costo de una búsqueda es O (n) en lugar de O (1).
fuente
default(KeyValuePair<T, U>)
no esnull
, es unKeyValuePair
dóndeKey=default(T)
yValue=default(U)
. Por lo tanto, no puede usar el?.
operador en el ejemplo de LINQ; tendrá que tomarFirstOrDefault()
y luego (para este caso en particular) verificar para ver siKey == null
.Para ustedes LINQers que nunca usan un constructor de diccionario regular:
fuente
No es muy elegante, pero en caso de que no pueda cambiar la creación del diccionario, y todo lo que necesita es un truco sucio, ¿qué tal esto:
fuente
ToUpperInvariant
lugar deToLower
. msdn.microsoft.com/en-us/library/dd465121%28v=vs.110%29.aspxvar item = MyDictionary.FirstOrDefault(x => x.Key.ToUpperInvariant() == keyValueToCheck.ToUpperInvariant());
dict.Keys.Contains("bla", appropriate comparer)
? Además, no será nulo para FirstOrDefault ya que keyvaluepair en C # es una estructura.