2012-06-08 25 views
8

Me gustaría utilizar un tipo que se comporta como una lista simple de pares [(a,b)] que sirve como diccionario, asignando claves del tipo a a valores del tipo b, mientras se mantiene un "usuario -specified ", orden definido de claves. (es decir, al igual que con las listas ordinarias, me gustaría poder "agregar" un elemento que luego se reconoce como el "último elemento"). Sin embargo, me gustaría buscar acceso aleatorio en claves con un rendimiento mejor que lineal, es decir, qué Data.Map proporciona. Una opción sería la de simplemente mantener un mapa ordinaria, además de una lista de claves que define su orden:Un tipo de diccionario con un orden definido de claves

data OrderedDict a b = OrderedDict (Map a b) [a] 

y luego definir append operaciones, etc., que mantienen las dos colecciones principales sincronizados. Sin embargo, parece feo mantener dos colecciones separadas de las mismas claves. ¿Hay un tipo de datos ya preparado que ya combine teclas ordenadas con búsqueda de acceso aleatorio eficiente por clave?

+0

La [LinkedHashMap] de Java [http://docs.oracle.com/javase/6/docs/api/java/util/LinkedHashMap.html] parece hacer algo similar : inserta una lista de teclas a través del mapa. Python's OrderedDict es simplemente una lista de pares, por lo que no son de ayuda aquí. –

+1

¿Qué quiere decir con "orden definido"? Dadas dos teclas 'a1' y' a2', ¿se fija a priori si 'a1' precede a' a2' o es la precedencia determinada en tiempo de ejecución? – Peter

+1

@peter Me refiero a 'orden definida' en el mismo sentido que con listas ordinarias - si añado 'a2' después de anexar' a1', entonces 'a1' precede a' a2' – gcbenison

Respuesta

3

A menos que malinterprete por completo su pregunta, Data.Map hace exactamente esto, utilizando la instancia del tipo de clave Ord para ordenar. Como es un árbol binario, la implementación también mantiene las claves ordenadas.

Data.Map.keys le da las teclas de un mapa en orden ascendente; como las transformaciones, como map, de un mapa son puramente funcionales, el orden de recorrido es irrelevante, y todas las formas de obtener una secuencia de claves o pares clave/valor de un mapa le dan una lista ordenada.

+9

Creo que gcbenison está pidiendo algo como 'Data .Map' pero con la propiedad adicional de preservar el orden en que se insertan las claves. – huon

+0

Si tiene un tipo de clave personalizada, puede hacer que defina su propio orden. Aunque eso solo funciona si la orden puede ser generada procesalmente. – Evi1M4chine

3

Si lo que desea es conservar algunas fija fin (por ejemplo, tiempo de inserción), además de tener O (log n) operaciones de búsqueda/inserciones, simplemente podría utilizar múltiples mapas y actualizar de forma simultánea:

  1. Map a b para almacenar los datos reales, y
  2. Map Int a que le proporciona la i-ésima clave en el pedido. (Si también necesita consultar el índice de una clave dada se podría añadir un Map a Int)
4

Tome un vistazo a ixset biblioteca - que le permite mantener conjuntos indexados por múltiples columnas (por a y por Int en su caso). Esto es mucho más fácil de mantener que mantener los mapas consistentes a mano

+0

Gracias - 'ixset' es genial. No creo que coincida exactamente con la factura en este caso porque puede permitir el estado incoherente (entradas múltiples con el mismo campo 'Int') y requeriría que un llamador realizara una operación' append' para especificar explícitamente el índice, algo que no requerido por listas ordinarias. – gcbenison

Cuestiones relacionadas