¿Hay alguna clase de diccionario en la biblioteca de clases base .NET que permita usar claves duplicadas? La única solución que he encontrado es crear, por ejemplo, una clase como:
Dictionary<string, List<object>>
Pero esto es bastante irritante para usar realmente. En Java, creo que un MultiMap logra esto, pero no puede encontrar un análogo en .NET.
c#
.net
dictionary
multimap
Caracol mecánico
fuente
fuente
{ a, 1 }
y{ a, 2 }
en una tabla hash dondea
está la clave, una alternativa es tener{ a, [1, 2] }
.Respuestas:
Si está utilizando .NET 3.5, use la
Lookup
claseEDITAR: generalmente crea un
Lookup
usoEnumerable.ToLookup
. Esto supone que no es necesario cambiarlo después, pero normalmente encuentro que es lo suficientemente bueno.Si eso no funciona para usted, no creo que haya nada en el marco que lo ayude, y usar el diccionario es tan bueno como parece :(
fuente
Lookup
no es serializableLa clase Lista en realidad funciona bastante bien para colecciones de clave / valor que contienen duplicados en los que desea iterar sobre la colección. Ejemplo:
fuente
Aquí hay una forma de hacerlo con List <KeyValuePair <string, string>>
Salidas k1 = v1, k1 = v2, k1 = v3
fuente
Si usa cadenas como claves y valores, puede usar System.Collections.Specialized.NameValueCollection , que devolverá una matriz de valores de cadena a través del método GetValues (clave de cadena).
fuente
Acabo de encontrar la biblioteca PowerCollections que incluye, entre otras cosas, una clase llamada MultiDictionary. Esto envuelve perfectamente este tipo de funcionalidad.
fuente
Nota muy importante sobre el uso de la búsqueda:
Puede crear una instancia de a
Lookup(TKey, TElement)
llamandoToLookup
a un objeto que implementeIEnumerable(T)
No hay un constructor público para crear una nueva instancia de a
Lookup(TKey, TElement)
. Además, losLookup(TKey, TElement)
objetos son inmutables, es decir, no puede agregar o eliminar elementos o claves de unLookup(TKey, TElement)
objeto después de que se haya creado.(de MSDN)
Creo que esto sería un espectáculo para la mayoría de los usos.
fuente
Creo que algo así
List<KeyValuePair<object, object>>
haría el trabajo.fuente
Si está usando> = .NET 4, entonces puede usar
Tuple
Class:fuente
List<KeyValuePair<key, value>>
solución como la anterior. ¿Me equivoco?Es bastante fácil "rodar su propia versión" de un diccionario que permite entradas de "clave duplicada". Aquí hay una implementación simple y aproximada. Es posible que desee agregar soporte para básicamente la mayoría (si no todos) en
IDictionary<T>
.Un ejemplo rápido sobre cómo usarlo:
fuente
En respuesta a la pregunta original. Algo así
Dictionary<string, List<object>>
se implementa en una clase llamadaMultiMap
en TheCode Project
.Puede encontrar más información en el siguiente enlace: http://www.codeproject.com/KB/cs/MultiKeyDictionary.aspx
fuente
NameValueCollection admite múltiples valores de cadena bajo una clave (que también es una cadena), pero es el único ejemplo que conozco.
Tiendo a crear construcciones similares a la de su ejemplo cuando me encuentro con situaciones en las que necesito ese tipo de funcionalidad.
fuente
Al usar la
List<KeyValuePair<string, object>>
opción, puede usar LINQ para hacer la búsqueda:fuente
Desde el nuevo C # (creo que es de 7.0), también puede hacer algo como esto:
y lo está utilizando como una lista estándar, pero con dos valores nombrados como desee
fuente
¿Quieres decir congruente y no un duplicado real? De lo contrario, una tabla hash no podría funcionar.
Congruente significa que dos claves separadas pueden dividir en hash al valor equivalente, pero las claves no son iguales.
Por ejemplo: supongamos que la función hash de su tabla hash era simplemente hashval = key mod 3. Tanto 1 como 4 se asignan a 1, pero son valores diferentes. Aquí es donde entra en juego tu idea de una lista.
Cuando necesita buscar 1, ese valor se divide en 1, la lista se recorre hasta que se encuentra la Clave = 1.
Si permitiera insertar claves duplicadas, no podría diferenciar qué claves se asignan a qué valores.
fuente
La forma en que uso es solo un
Dictionary<string, List<string>>
De esta manera, tiene una sola tecla que contiene una lista de cadenas.
Ejemplo:
fuente
Me topé con esta publicación en busca de la misma respuesta, y no encontré ninguna, así que preparé una solución de ejemplo básica usando una lista de diccionarios, anulando el operador [] para agregar un nuevo diccionario a la lista cuando todos los demás tienen un clave dada (conjunto) y devuelve una lista de valores (get).
Es feo e ineficiente, SOLO obtiene / establece por clave, y siempre devuelve una lista, pero funciona:
fuente
Cambié la respuesta de @Hector Correa a una extensión con tipos genéricos y también le agregué un TryGetValue personalizado.
fuente
Este es un diccionario simultáneo de remolque, creo que esto te ayudará:
ejemplos:
fuente
yo uso esta clase simple:
uso:
fuente
Puede crear su propio contenedor de diccionario, algo como este, como beneficio adicional, admite un valor nulo como clave:
La muestra de uso:
fuente
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 }
U puede definir un método para construir una clave de cadena compuesta cada vez que quiera usar el diccionario. Debe usar este método para construir su clave, por ejemplo:
Para usar:
fuente
Las claves duplicadas rompen el contrato completo del Diccionario. En un diccionario, cada clave es única y se asigna a un solo valor. Si desea vincular un objeto a un número arbitrario de objetos adicionales, la mejor opción podría ser algo similar a un DataSet (en el lenguaje común de una tabla). Coloque sus claves en una columna y sus valores en la otra. Esto es significativamente más lento que un diccionario, pero esa es su compensación por perder la capacidad de trocear los objetos clave.
fuente
También esto es posible:
De esta manera, podemos tener claves únicas. Espero que esto funcione para usted.
fuente
Puede agregar las mismas teclas con mayúsculas y minúsculas como:
key1
Clave1
TECLA1
key1
key1
key1
Sé que es una respuesta ficticia, pero funcionó para mí.
fuente