2010-09-03 16 views
25

Necesito un diccionario como objeto que puede almacenar entradas múltiples con la misma clave. ¿Está disponible como colección estándar, o tengo que hacer la mía?Un diccionario con entradas múltiples con la misma clave

Para aclarar, yo quiero ser capaz de hacer algo como esto:

var dict = new Dictionary<int, String>(); 
dict.Add(1, "first"); 
dict.Add(1, "second"); 

foreach(string x in dict[1]) 
{ 
    Console.WriteLine(x); 
} 

Salida:

first 
second 
+0

¿Está buscando utilizar específicamente un int para la clave? Si una cadena fuera suficiente, NameValueCollection puede ser útil: se pueden asignar varios valores a una clave –

Respuesta

42

En .NET 3.5 puede usar un Lookup en lugar de un diccionario.

var items = new List<KeyValuePair<int, String>>(); 
items.Add(new KeyValuePair<int, String>(1, "first")); 
items.Add(new KeyValuePair<int, String>(1, "second")); 
var lookup = items.ToLookup(kvp => kvp.Key, kvp => kvp.Value); 

foreach (string x in lookup[1]) 
{ 
    Console.WriteLine(x); 
} 

La clase Lookup es inmutable. Si desea una versión mutable, puede usar EditableLookup desde MiscUtil.

+1

De los documentos: * No hay un constructor público para crear una nueva instancia de Lookup . Además, los objetos Lookup son inmutables, es decir, no se pueden agregar o eliminar elementos o claves de un objeto Lookup después de que se haya creado. * – Douglas

+0

@Douglas: Gracias por el comentario. He actualizado mi respuesta para cubrir este punto. –

9

Yo recomendaría hacer algo como esto:

var dict = new Dictionary<int, HashSet<string>>(); 
dict.Add(1, new HashSet<string>() { "first", "second" }); 
6

Dictionary<T,K> no es compatible con este comportamiento y no hay ningún tipo de colección en la biblioteca de la clase base que proporcione dicho comportamiento. La forma más fácil es construir una estructura de datos compuesta así:

var data = new Dictionary<int, List<string>>(); 

A medida que el segundo parámetro se debe utilizar una colección que ofrece las cualidades que está buscando, es decir, orden estable ⇒ List<T>, acceso rápido HashSet<T>, etc.

1

Lo que estás buscando no es realmente un diccionario en el sentido tradicional (ver Associative Array).

No hay ninguna clase, por lo que yo sé, que ofrece esto en el marco (System.Linq.Lookup no expone un constructor), pero se puede crear una clase que implementa mismo ILookup<TKey, TElement>

0

tal vez podría utilizar un diccionario en su clave principal, en la que cada elemento es una lista u otra colección en su clave secundaria. Para agregar un elemento a su estructura de datos, vea si existe la clave principal. De lo contrario, cree una nueva lista de elementos individuales con su Valor y guárdela en el diccionario. Si la clave principal existe, agregue su valor a la lista que está en el diccionario.

2

Definitivamente quiere utilizar NameValueCollection:

usando System.Collections.Specialized;

NameValueCollection nvc = new NameValueCollection(); 
nvc.Add("pets", "Dog"); 
nvc.Add("pets", "Rabbit"); 
Console.WriteLine(nvc["pets"]); 
//returns Dog,Rabbit 
+5

NVC solo funciona con cadenas. – oillio

Cuestiones relacionadas