Existem classes de dicionário na biblioteca de classes base do .NET que permitem que chaves duplicadas sejam usadas? A única solução que encontrei é criar, por exemplo, uma classe como:
Dictionary<string, List<object>>
Mas isso é bastante irritante para realmente usar. Em Java, acredito que um MultiMap realiza isso, mas não consegue encontrar um analógico no .NET.
c#
.net
dictionary
multimap
Caracol mecânico
fonte
fonte
{ a, 1 }
e{ a, 2 }
em uma tabela de hasha
a chave, uma alternativa é ter{ a, [1, 2] }
.Respostas:
Se você estiver usando o .NET 3.5, use o
Lookup
classeEDIT: você geralmente cria um
Lookup
usandoEnumerable.ToLookup
. Isso pressupõe que você não precise alterá-lo posteriormente - mas normalmente acho que isso é bom o suficiente.Se isso não funcionar para você, acho que não há nada na estrutura que ajude - e usar o dicionário é o melhor possível :(
fonte
Lookup
não é serializávelA classe List realmente funciona muito bem para coleções de chave / valor que contêm duplicatas nas quais você deseja iterar sobre a coleção. Exemplo:
fonte
Aqui está uma maneira de fazer isso com List <KeyValuePair <string, string>>
Saídas k1 = v1, k1 = v2, k1 = v3
fonte
Se você estiver usando cadeias de caracteres como as chaves e os valores, poderá usar System.Collections.Specialized.NameValueCollection , que retornará uma matriz de valores de string por meio do método GetValues (string string).
fonte
Acabei de encontrar a biblioteca do PowerCollections , que inclui, entre outras coisas, uma classe chamada MultiDictionary. Isso envolve perfeitamente esse tipo de funcionalidade.
fonte
Nota muito importante sobre o uso da pesquisa:
Você pode criar uma instância de a
Lookup(TKey, TElement)
chamandoToLookup
um objeto que implementaIEnumerable(T)
Não há construtor público para criar uma nova instância de a
Lookup(TKey, TElement)
. Além disso, osLookup(TKey, TElement)
objetos são imutáveis, ou seja, você não pode adicionar ou remover elementos ou chaves de umLookup(TKey, TElement)
objeto depois que ele foi criado.(do MSDN)
Eu acho que isso seria uma rolha de show para a maioria dos usos.
fonte
Eu acho que algo como
List<KeyValuePair<object, object>>
faria o trabalho.fonte
Se você estiver usando> = .NET 4, poderá usar a
Tuple
Classe:fonte
List<KeyValuePair<key, value>>
solução como a acima. Estou errado?É fácil o suficiente "rolar sua própria" versão de um dicionário que permita entradas de "chave duplicada". Aqui está uma implementação simples e aproximada. Você pode considerar adicionar suporte para basicamente a maioria (se não todos)
IDictionary<T>
.Um exemplo rápido de como usá-lo:
fonte
Em resposta à pergunta original. Algo como
Dictionary<string, List<object>>
é implementado em uma classe chamadaMultiMap
TheCode Project
.Você pode encontrar mais informações no link abaixo: http://www.codeproject.com/KB/cs/MultiKeyDictionary.aspx
fonte
O NameValueCollection oferece suporte a vários valores de string em uma chave (que também é uma string), mas é o único exemplo que eu conheço.
Costumo criar construções semelhantes à do seu exemplo quando encontro situações em que preciso desse tipo de funcionalidade.
fonte
Ao usar a
List<KeyValuePair<string, object>>
opção, você pode usar o LINQ para fazer a pesquisa:fonte
Desde o novo C # (acredito que seja do 7.0), você também pode fazer algo assim:
e você está usando-o como uma lista padrão, mas com dois valores nomeados como quiser
fonte
Você quer dizer congruente e não uma duplicata real? Caso contrário, uma hashtable não seria capaz de funcionar.
Congruent significa que duas chaves separadas podem hash para o valor equivalente, mas as chaves não são iguais.
Por exemplo: digamos que a função hash da sua hashtable era apenas hashval = mod da chave 3. Ambos 1 e 4 são mapeados para 1, mas são valores diferentes. É aqui que a sua ideia de lista entra em jogo.
Quando você precisa procurar 1, esse valor é um hash para 1, a lista é percorrida até que a Chave = 1 seja encontrada.
Se você permitisse a inserção de chaves duplicadas, não conseguiria diferenciar quais chaves são mapeadas para quais valores.
fonte
O jeito que eu uso é apenas um
Dictionary<string, List<string>>
Dessa forma, você tem uma única chave segurando uma lista de cadeias.
Exemplo:
fonte
Eu tropecei neste post em busca da mesma resposta e não encontrei nenhuma, então montei uma solução de exemplo básico usando uma lista de dicionários, substituindo o operador [] para adicionar um novo dicionário à lista quando todos os outros tiverem um chave fornecida (conjunto) e retorne uma lista de valores (get).
É feio e ineficiente, apenas recebe / define por chave e sempre retorna uma lista, mas funciona:
fonte
Alterei a resposta do @Hector Correa para uma extensão com tipos genéricos e também adicionei um TryGetValue personalizado.
fonte
Este é um dicionário simultâneo de duas maneiras. Acho que isso ajudará você:
exemplos:
fonte
eu uso essa classe simples:
uso:
fonte
Você pode criar seu próprio wrapper de dicionário, algo como este, como um bônus que suporta valor nulo como chave:
A amostra de uso:
fonte
var dictionary = new OpenDictionary<string, int>(); dictionary.Add("1", 1); // The next line won't throw an exception; dictionary.Add("1", 2); dictionary.TryGetEntries("1", out List<int> result); // result is { 1, 2 }
Você pode definir um método para criar uma chave de cadeia de caracteres composta em todos os lugares em que você deseja usar o dicionário. Você deve usar esse método para criar sua chave, por exemplo:
para usar:
fonte
Chaves duplicadas quebram todo o contrato do Dicionário. Em um dicionário, cada chave é única e mapeada para um único valor. Se você deseja vincular um objeto a um número arbitrário de objetos adicionais, a melhor aposta pode ser algo semelhante a um DataSet (na linguagem comum, uma tabela). Coloque suas chaves em uma coluna e seus valores na outra. Isso é significativamente mais lento que um dicionário, mas essa é sua desvantagem por perder a capacidade de fazer o hash dos objetos principais.
fonte
Também isso é possível:
Dessa forma, podemos ter chaves únicas. Espero que funcione para voce.
fonte
Você pode adicionar as mesmas chaves com diferentes casos, como:
key1
Key1
KEY1
KeY1
kEy1
keY1
Eu sei que é uma resposta idiota, mas funcionou para mim.
fonte