Converter IDictionary chaves para minúsculas (C #)
-
03-07-2019 - |
Pergunta
Eu tenho um método que obtém um IDictionary como parâmetro. Agora eu quero fornecer um método que recupera o valor deste dicionário, mas deve ser caso invariante.
Assim, a minha solução para isso agora era ter uma função estática que percorre as chaves e os converte ToLower () como este:
private static IDictionary<ILanguage, IDictionary<string, string>> ConvertKeysToLowerCase(
IDictionary<ILanguage, IDictionary<string, string>> dictionaries)
{
IDictionary<ILanguage, IDictionary<string, string>> resultingConvertedDictionaries
= new Dictionary<ILanguage, IDictionary<string, string>>();
foreach(ILanguage keyLanguage in dictionaries.Keys)
{
IDictionary<string, string> convertedDictionatry = new Dictionary<string, string>();
foreach(string key in dictionaries[keyLanguage].Keys)
{
convertedDictionatry.Add(key.ToLower(), dictionaries[keyLanguage][key]);
}
resultingConvertedDictionaries.Add(keyLanguage, convertedDictionatry);
}
return resultingConvertedDictionaries;
}
Agora, isso é ok, mas ainda é um muito grande pedaço de código que contradiz a minha ideia de "limpa e eficiente". Sabe quaisquer alternativas a este para que o método .ContainsKey () do dicionário não faz diferença entre invólucro?
Solução
Sim. - passar o construtor StringComparer.OrdinalIgnoreCase
dicionário (ou outro comparer caso-ignorando, dependendo de suas necessidades cultura de sensibilidade)
Jon
Outras dicas
Usando um StringDictionary as chaves são convertidos para minúsculas na criação de tempo.
http: //simiansoftware.blogspot .com / 2008/11 / ter-const-string-com-ui-description.html
Você pode usar o var palavra-chave para remover alguma desordem. Tecnicamente, a fonte permanece a mesma. Também gostaria de simplesmente passar e retornar um Dictionary
private static IDictionary<string, string> ConvertKeysToLowerCase(
IDictionary<string, string> dictionaries)
{
var convertedDictionatry = new Dictionary<string, string>();
foreach(string key in dictionaries.Keys)
{
convertedDictionatry.Add(key.ToLower(), dictionaries[key]);
}
return convertedDictionatry;
}
... e chamá-lo assim:
// myLanguageDictionaries is of type IDictionary<ILanguage, IDictionary<string, string>>
foreach (var dictionary in myLanguageDictionaries.Keys)
{
myLanguageDictionaries[dictionary].Value =
ConvertKeysToLowerCase(myLanguageDictionaries[dictionary].Value);
}
Você pode herdar de IDictionary si mesmo, e chamadas simplesmente marechal para uma instância dicionário interno.
Add(string key, string value) { dictionary.Add(key.ToLowerInvariant(), value) ; }
public string this[string key]
{
get { return dictionary[key.ToLowerInvariant()]; }
set { dictionary[key.ToLowerInvariant()] = value; }
}
// And so forth.
System.Collections.Specialized.StringDictionary () ajuda maio. estados MSDN:
"A chave é tratado de uma forma maiúsculas e minúsculas;. É traduzido para minúsculas antes de ser usado com o dicionário corda
Em .NET Framework versão 1.0, esta classe usa comparações de cadeia sensível à cultura. No entanto, em .NET Framework versão 1.1 e posterior, essa classe usa CultureInfo.InvariantCulture ao comparar strings. Para mais informações sobre como a cultura afeta comparações e classificação, consulte Comparando e classificando dados para uma específica cultura e Execução de operações de Cordas diferenciação de cultura. "
versão LINQ usando os métodos de extensão IEnumerable<T>
:
private static IDictionary<ILanguage, IDictionary<string, string>> ConvertKeysToLowerCase(
IDictionary<ILanguage, IDictionary<string, string>> dictionaries)
{
return dictionaries.ToDictionary(
x => x.Key, v => CloneWithComparer(v.Value, StringComparer.OrdinalIgnoreCase));
}
static IDictionary<K, V> CloneWithComparer<K,V>(IDictionary<K, V> original, IEqualityComparer<K> comparer)
{
return original.ToDictionary(x => x.Key, x => x.Value, comparer);
}