2011-09-22 19 views
9

Tengo una estructura de diccionario, con múltiples pares de valores clave dentro.¿Cómo insertar como primer elemento en el diccionario?

myDict.Add(key1, value1); 
myDict.Add(key2, value2); 
myDict.Add(key3, value3); 

Mi diccionario se utiliza como fuente de datos para cierto control. En desplegable del control veo los artículos son así:

key1 
key2 
key3 

El orden parece idéntica a mi diccionario. Sé que Dictionary no es como arrayList: puede obtener el índice más o menos. No puedo usar sortedDictionary. Ahora tengo que añadir una más par de valores clave para este diccionario en algún punto de mi programa y espero que tenga el mismo efecto que hago esto:

myDict.Add(newKey, newValue); 
myDict.Add(key1, value1); 
myDict.Add(key2, value2); 
myDict.Add(key3, value3); 

Si hago esto, sé NewKey mostrará en mi control como primer elemento.

Tengo una idea para crear un tempDict, poner cada par de myDict a tempDict, y luego despejado myDict, a continuación, añadir pares de vuelta de esta manera:

myDict.Add(newKey, newValue); 
myDict.Add(key1, value1); 
myDict.Add(key2, value2); 
myDict.Add(key3, value3); 

¿Hay mejor manera de que esto?

Gracias!

Respuesta

19

Dictionary<K,V> hace no tenga un pedido. Cualquier mantenimiento de orden percibido es por casualidad (y un artefacto de una implementación particular que incluye, pero no se limita a, orden de selección y recuento de cubos).

Estos son los enfoques (simplemente utilizando el Base Class Libraries BCL) que sé sobre: ​​

  1. Lookup<K,V>
    • .NET4, inmutable, puede asignar claves de múltiples valores (reloj para duplicados durante la construcción)
  2. OrderedDictionary
    • Viejo, no genérico, esperado Dictionary perfor límites Mance (otros dos enfoques son O(n) para "obtener (llave)/set (llave)")
  3. List<KeyValuePair<K,V>>
    • .NET2/3 bien, mutable, más trabajo de campo, puede asignar claves para varios valores (ver si hay duplicados en inserciones)

feliz de codificación.


Creación de una estructura de datos hash que mantiene el orden de inserción es en realidad sólo una ligera modificación de una aplicación de hash estándar (Rubí hashes ahora mantener el orden de inserción); sin embargo, esto no se hizo en .NET ni, más importante aún, es parte del contrato de Dictionary/IDictionary.

+0

¿Qué quiere decir con "ver insertos" en la búsqueda ? ¿Quiere decir que hay que tener cuidado al insertar valores en una búsqueda ? Si es así, eso no es cierto, porque Lookup es inmutable. – phoog

+0

@phoog Como * puede * manejar una sola tecla para múltiples valores, es posible llevar a situaciones que no son posibles con un diccionario. La redacción no fue ideal. –

+0

+1 para esta respuesta pendiente –

1

No utilice un diccionario; no hay garantía de que el orden de las teclas no cambiará cuando agregue más elementos.En su lugar, defina una clase Pair para sus pares clave-valor (vea aquí What is C# analog of C++ std::pair? como ejemplo) y use un List<Pair> para su fuente de datos. El List tiene una operación Insert que puede usar para insertar nuevos elementos en cualquier lugar de su lista.

+0

pero mi control necesita un diccionario para alimentar la fuente de datos y no queremos cambiar el control. – spspli

+1

@spspli: lo que el buen doctor dice es que no puede ignorar los conceptos básicos del 'Dictionary '. Entonces, o cambias tu estructura de datos o vives con una colección desordenada. – user7116

+3

Cuando desee que su control muestre elementos en un orden específico similar a una lista, y la única fuente de datos permitida es un diccionario, que no proporciona un orden específico, entonces su control está mal diseñado y no puede esperar encontrar una solución para su problema. Entonces, o cambias tu control, usas un control diferente o descubres más sobre tu control si hay una forma alternativa de obtener la información de ordenamiento desde afuera. –

2

Desde la página de MSDN en diccionario (TKey, TValue):

Para los propósitos de la enumeración, cada elemento en el diccionario es tratado como un KeyValuePair < (De < (TKey, TValue>)>) Estructura representando un valor y su clave. El orden en que se devuelven los artículos no está definido.

Supongo que no puede utilizar SortedDictionary porque el control depende de que su fuente de datos sea un diccionario. Si el control espera tanto el tipo de diccionario como los datos ordenados, el control debe modificarse, porque esos dos criterios se contradicen entre sí. Usted debe utilizar un tipo de datos diferente si necesita la funcionalidad de ordenar/ordenar. Dependiendo de un comportamiento indefinido, es buscar problemas.

5

No puede hacer eso con la clase Dictionary. Está funcionando en su ejemplo debido a una peculiaridad en la forma en que se implementa la estructura de datos. La estructura de datos en realidad almacena las entradas en orden temporal en una matriz y luego utiliza otra matriz para indexar en la matriz de entrada. Las enumeraciones se basan en la matriz de entrada. Es por eso que parece estar ordenado en su caso. Pero, si aplica una serie de operaciones de extracción e inserción, notará que este orden se altera.

Use KeyCollection en su lugar. Proporciona O (1) recuperación por clave e índice y conserva el orden temporal.

+0

+1 Desearía saber algo de KeyCollection antes (pero ¿por qué está desactivado en el espacio de nombres de ComponentModel y por qué se basa en su extensión?: - /) –

+0

@pst: No tengo ni idea ... buena pregunta. –

+0

+1 [KeyedCollection] (http://msdn.microsoft.com/en-us/library/ms132438.aspx) es justo lo que estaba buscando. – Ben

1

Diccionario No se debe utilizar para ordenar objetos, sino que debe utilizarse para buscar objetos. Sugeriría algo más si también quieres que ordene los objetos.

Si expande el diccionario, no hay ninguna regla que impida que se mezcle su lista.

Cuestiones relacionadas