2009-02-16 20 views
18

Duplicar posibles:
C# Sortable collection which allows duplicate keys¿Hay alguna alternativa a Dictionary/SortedList que permita duplicados?

Básicamente me gustaría hacer una obra diccionario con claves duplicadas sin entrar en implementaciones Comparer personalizado. Hay una idea de:

Dictionary<key, List<value>> 

pero todavía tiene algunos gastos generales. Ojalá Dictionary tuviera "AllowDuplicates".

+0

No lo encontré en mis búsquedas. Votado para cerrar, gracias. –

+0

También relacionado: http: // stackoverflow.com/questions/5716423/c-sharp-sortable-collection-which-allows-duplicate-keys –

Respuesta

13

Si está utilizando .NET 3.5 entonces Lookup es probablemente lo que está buscando.

+4

Es una pena que una clase potencialmente útil tenga algunas limitaciones. Como ningún constructor público o la capacidad de agregar/eliminar elementos. – Ray

+2

@Ray, estoy de acuerdo por completo. Aunque supongo que es por eso que se llama Lookup en lugar de algo como MultiDictionary, para insinuar que es una búsqueda inmutable de algún tipo en lugar de una colección para ser manipulada. La sugerencia de OP de una Dictionary > sería mucho más flexible. – LukeH

+0

@Ray: el mejor constructor es, y cito MSDN: "Puede crear una instancia de una búsqueda llamando a ToLookup en un objeto que implementa IEnumerable . " –

3

No en el Fx < 3.5 .. Puede implementar uno, obviamente, con un Diccionario de objetos IList. Pero luego tienes el problema/responsabilidad de encapsulación.

Si está utilizando .NET 3.5, use la clase Lookup.

+0

Es solo un reemplazo para 'Dictionary', pero no para' SortedList'. –

0

Por definición, un diccionario contiene claves únicas. Su ejemplo anterior es efectivamente una especie de matriz con dos dimensiones, una estructura que he usado muchas veces. ¿Por qué querrías tener llaves duplicadas? Si lo hiciera, ¿cómo abordaría el Diccionario de forma exclusiva sus miembros?

+5

Considere un diccionario del mundo real que enumera diferentes significados para la misma palabra. Varias entradas con una clave común. Nada contradictorio sobre eso. Los miembros pueden ser atendidos mediante una búsqueda devolviendo una colección o Enumerable. C++ ha tenido un multimap por edades. No es un problema imposible. :) – jalf

1

me encontré con el mismo problema .. necesitaba un sortedList que puede permitir claves duplicadas ..

var sortList = new SortedList<string, IDictionary<string, object>>(); 

pero esto no funcionó .. así que utilicé

var list = new List<KeyValuePair<string, IDictionary<string, object>>>(); 

añadir nuevos datos a como ..

list.Add(new KeyValuePair<string, IDictionary<string, object>>>(value, Dictionary)); 

con LINQ me lo solucionaron sin ningún problema ..

Trate List<KeyValuePair<TKey, List<TValue>>>();

+4

No olvide que esto Costo de búsqueda O (N) por clave a diferencia de una tabla hash (o un diccionario), que es O (1) principalmente. –

4

puede seguir utilizando SortedList y tratar de hacer una clave única por la combinación de su valor y un GUID en una clase. En este caso, debe implementar la IComparer<NewKey> para su nueva clave, algo así como:

class MyKey 
{ 
    public Guid Guid { get; set; } 
    public float Value { get; set; } 
} 

class MyComparer : IComparer<MyKey> 
{ 

    public int Compare(MyKey x, MyKey y) 
    { 
     if (x == null || y == null) 
      throw new InvalidOperationException("both of parameters must be not null"); 
     if (x.Value < y.Value) return -1; 
     if (x.Value > y.Value) return 1; 
     return 0; 
    } 
} 

y luego

var mySortedList = new SortedList<MyKey, MyValue>(new MyComparer()); 
2

que no funciona. Tan pronto como devuelva 0 del comparador, emitirá una excepción "duplicada".

No necesita encapsulación de clases ni nada, simplemente haga un comparador que no devuelva 0 (igual) resultado. Aquí hay un ejemplo para int tipo de clave

class MyComparer : IComparer<int> 
{ 

    public int Compare(int x, int y) 
    { 
    if (x < y) 
     return -1; 
    else return 1; 
    } 
} 
+3

Tenga en cuenta que este truco romperá el indexador. Si intenta obtener un valor utilizando el indexador, obtendrá una excepción porque no se pudo encontrar la clave. –

Cuestiones relacionadas